Множество Жюлиа
Создание фрактальной анимации на основе множества Жюлиа
Введение
В 1918 году французский учёный Гастон Жюлиа исследовал поведение комплексных функций при итерациях, но лишь с появлением компьютеров мир увидел скрытую в его уравнениях красоту.
Множество Жюлиа — это визуальное воплощение границы между порядком и хаосом. Простое уравнение создаёт бесконечное разнообразие самоподобных фракталов, где каждая точка устремляется в бесконечность или остаётся в ограниченной области.
В данном примере мы рассмотрим, как с помощью комплексных чисел, итераций и цветовых схем, создать анимацию фигуры множества Жюлиа, изменяющую своё состояние в зависимости от изменяющегося угла константы.
Присоединим необходимые библиотеки.
#import Pkg
#Pkg.add(["LinearAlgebra", "Printf", "ProgressMeter", "FileIO", "Images", "ColorSchemes", "VideoIO"])
using LinearAlgebra, Printf, ProgressMeter, FileIO, Images, ColorSchemes, VideoIO
Параметры фигуры и анимации
Определим параметры анимации. Необходимые параметры:
- продолжительность анимации;
- ширина кадра;
- высота кадра;
- количество кадров в секунду;
- начальный угол константы;
- конечный угол константы;
- радиус фигуры;
- количество итераций;
- размеры комплексной плоскости (преобразуются пропорционально ширине и высоте кадра).
сек = 60 # продолжительность анимации
ш = 1920 # ширина кадра
в = 1080 # высота кадра
квс = 60 # кадров в секунду
α = 2π*0.14 # начальный угол константы
β = 2π*0.86 # конечный угол константы
r = 0.78 # радиус
итер = 20 # количество итераций
л = 1.5 # линейная ширина комплексной плоскости
Комплексная плоскость
На основании исходных, вычислим количество кадров в анимации и создадим массивы чисел для комплексной плоскости. Где – массив вещественной части, – массив мнимой части.
кадры = сек * квс # всего кадров
# Создание комплексной плоскости
X = [x for y in range(-л, л, length=в), x in range(-л, л, length=ш)];
Y = [y for y in range(-л, л, length=в), x in range(-л, л, length=ш)];
Функция с выражением и итерациями
Определим функцию, которая вычисляет каждое комплексное число и производит итерации вычисления функции и подстановки полученных значений в аргумент функции.
Функция определяется следующим образом:
,
где:
,
,
- изменяющийся угол константы, влияющий на анимацию фигуры,
- мнимая единица.
function Жюлиа(X, Y, a, r, итер)
Z = X .+ im .* Y
C = r .* cos(a) .+ im .* r .* sin(a)
for k in 1:итер
Z = Z .^ 2 .+ C
end
return exp.(-abs.(Z)), C
end
Создание субтитров
Определим функцию, которая создаёт субтитры в формате srt для отображения текущего значения Z, соответствующего текущему состоянию фигуры.
function кадр_время(к, квс)
T = zeros(UInt32, 4)
квч = 3600 * квс # кадры в час
квм = 60 * квс # кадры в минуту
бч = mod(к, квч) # кадры без часов
бм = mod(бч, квм) # кадры без минут и часов
T[1] = (к - бч) ÷ квч # часы
T[2] = (бч - бм) ÷ квм # минуты
T[4] = mod(бм, квс) # кадры без секунд, минут и часов
T[3] = (бм - T[4]) ÷ квс # секунды
мс = round(Int, 999 * T[4] / (квс - 1))
субт = string(lpad(T[1], 2, '0'), ':', lpad(T[2], 2, '0'), ':', lpad(T[3], 2, '0'), ',', lpad(мс, 3, '0'))
return субт
end
Создание анимации
Создадим шкалу прогресса и запустим процесс создания анимации.
кадр = 0
t = 0.0
время = 0.0
видео = []
п = Progress(кадры, 1, "Создание анимации:")
субтитры = open("Множество Жюлиа.srt", "w")
ProgressMeter.ijulia_behavior(:clear)
for a in range(α + (β - α)/кадры, stop = β, step = (β - α)/кадры)
старт = time()
время += t
кадр += 1
скорость = кадр / max(время, 0.001)
осталось = (кадры - кадр) / скорость
ProgressMeter.next!(п; showvalues = [(:Время, @sprintf "%d секунд" round(Int, время)), (:Создано, @sprintf "%d кадров" кадр), (:Скорость, @sprintf "%.4f кадров в секунду" скорость), (:Осталось, @sprintf "%d секунд" round(Int, осталось))])
J, C = Жюлиа(X, Y, a, r, итер)
J[isnan.(J)] .= 0.0
push!(видео, convert.(RGB{N0f8}, get.(Ref(ColorSchemes.magma), clamp.(J, 0.0, 1.0))))
write(субтитры, string(string(кадр), "\n", кадр_время(кадр-1, квс), " --> ", кадр_время(кадр, квс), "\n", "f(z) = z² ", real(C) >= 0 ? "+ " : "- ", @sprintf("%.5f", abs(real(C))), " ", imag(C) >= 0 ? "+ " : "- ", @sprintf("%.5fi", abs(imag(C))), "\n\n"))
t = time() - старт
end
if !isempty(видео)
@info "Сохраняем видео..."
параметры = (crf=23, preset="medium")
VideoIO.save("Множество Жюлиа.mp4", видео, framerate=квс, encoder_options=параметры)
end
close(субтитры)
println("\nАнимация создана успешно!")
println(" - Всего кадров: $кадры")
println(" - Время создания: $(round(Int, время)) секунд")
println(" - Средняя скорость создания: $(round(кадры/время, digits=4)) кадров в секунду")
После завершения процесса создания анимации, в текущей папке появится видеофайл c фигурой:

Если в функции, вычисляющей итерации вместо выражение заменить на , а цветовую схему заменить на turbo, получим не менее интересную фигуру.

Если определить выражение как , заменив цветовую схему на rainbow, получим ещё более необычную фигуру.

Заключение
Созданная анимация множества Жюлиа демонстрирует не только эстетическую, но и прикладную ценность фрактальной геометрии. Алгоритмы, основанные на принципах итеративных преобразований комплексной плоскости, находят применение в различных научных и инженерных областях.
Ключевые направления применения
- Телекоммуникации.
Фрактальные антенны с самоподобной структурой обеспечивают многодиапазонность при минимальных габаритах, что критично для мобильных устройств и спутниковой связи. - Компьютерное моделирование.
Алгоритмы генерации фракталов используются для синтеза природных ландшафтов в компьютерной графике, а также для моделирования пористых материалов и биологических структур. - Медицинская диагностика.
Фрактальный анализ применяется в обработке медицинских изображений для количественной оценки сложности сосудов, нейронных сетей и легочной ткани. - Криптография и защита данных.
Детерминированный хаос фрактальных систем используется в генераторах псевдослучайных чисел и стеганографических методах.
Таким образом, от абстрактного математического объекта до практического инструмента — фракталы представляют собой важный мост между теоретической математикой и прикладными технологиями. Представленная методика анимации позволяет не только визуализировать эти концепции, но и экспериментировать с параметрами для исследования границ между порядком и хаосом в динамических системах.