Как построить множества Жюлиа
На прошлых занятиях мы с вами рассмотрели способы построения фракталов с помощью L-систем, предложенные венгерским биологом Аристидом Линденмайером в 1968 году, с помощью систем итерированных функций, разработанные Джоном Хатчинсоном и Майклом Барнсли в 1981 году. Но есть еще один довольно известный метод построения фракталов, с которого, фактически, и начался подъем этого научного направления – формирование фрактальных кривых как аттракторов динамических систем.
В период с 1917 по 1919 годы французский математик Гастон Жюлиа (1893-1978 гг.) одновременно с Пьером Фату (1878-1929 гг.) исследовали итерирование функций комплексного переменного. Они изучали поведение полиномов степени вида:


где — комплексные числа. Например, в самом простом случае, можно взять функцию вида:

И смотреть, как она себя будет вести на итерациях:

Это напоминает СИФ с одним сжимающим отображением. Но даже в таком простом варианте можно получать удивительные по красоте изображения. И мы с вами скоро в этом убедимся.

Итак, как же эта функция комплексного переменного способна генерировать фрактальные кривые? В данном случае, мы можем получить только два аттактора: первый в виде множества точек на единичной окружности; второй – точка ноль.
Почему именно такие аттракторы? Если кто из вас не знает, то любое комплексное число вида:

,

где a – действительная часть числа; b – мнимая часть; — мнимая единица. Можно представить как точку на комплексной плоскости:

Из этого рисунка хорошо видно, что точки, которые при большом числе итераций не уходят в бесконечность:

это те, для которых модуль комплексного числа z меньше или равен единице:

Например, если число по модулю равно 0,7, то постоянно возводя его в квадрат, будем получать все меньшие и меньшие значения, пока в пределе не дойдем до нуля. А единица в любой степени всегда единица:

Поэтому, здесь мы и получаем, что любая комплексная точка, лежащая на единичной окружности, на ней и остается при любом числе итераций функции комплексного переменного. И то же самое с нулем. То есть, аттрактор состоит из множества «устойчивых» точек, не меняющих свое положение при итерировании функции.
Множество точек на комплексной плоскости, которые не уходят в бесконечность при увеличении числа итераций n, образуют множества Жюлиа.
Однако, рисовать круги путем многократного повторения функции комплексной переменной – это не лучшее занятие. На что еще способны эти формулы?
Давайте сделаем простую вещь – добавим комплексное слагаемое и рассмотрим функцию вида:

Казалось бы, что это слагаемое может поменять? Но оно буквально разрывает круг и приводит к многочисленным причудливым фрактальным формам! Прежде чем посмотреть на очередное чудо, нужно выяснить, при каких значениях

функция при итерациях не будет уходить в бесконечность. Вы думаете это то же значение 1, как и в предыдущем случае? Нет, тут следует уже брать значение 2. Почему? Есть теорема, которая доказывает, что любое комплексное число в такой функции при

заведомо будет уходить в бесконечность. А, значит, она не принадлежит множеству Жюлиа. (Формулировку и доказательство этой теоремы можно найти практическим в любом учебнике по фрактальным процессам).

Например, вот так выглядят множества Жюлиа при разных значениях слагаемого c. Точки, которые закрашены черным цветом – это точки множества, а остальные – это точки вне множества.
Настало время и нам создать сие творение собственноручно. Идея алгоритмов, которые строят такие множества, следующая.

Мы сканируем множество точек на комплексной плоскости, например, в диапазоне [-2; 2] по мнимой и действительной осям. Каждая точка – это комплексное число:

Наша задача определить, относится ли эта точка к множеству Жюлиа или нет. Для этого, мы делаем n итераций для функции:

,
где c – заданное комплексное число (константа). Если окажется, что после n итераций модуль полученного комплексного числа меньше двух, то такую точку следует отнести к множеству Жюлиа:

Иначе, это точка фона.
Строим множества Жюлиа на Python
Давайте реализуем такой алгоритм на Python с использованием Pygame. Вначале мы инициализируем Pygame, следующим образом:
import pygame import os WHITE = (255, 255, 255) BLACK = (0, 0, 0) # ---------- чтобы окно появлялось в верхнем левом углу ------------ x = 20 y = 40 os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y) # -------------------------------------------------------------------- pygame.init() W = 1200 H = 600 sc = pygame.display.set_mode((W, H)) pygame.display.set_caption("Множества Жюлиа") sc.fill(WHITE) FPS = 30 # число кадров в секунду clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: exit() pygame.display.update() clock.tick(FPS)
Здесь вам должно быть все понятно, мы делали это несколько раз на прошлых занятиях. Далее, в программе (до главного цикла) определим комплексную константу, размер формируемого изображения, масштабный коэффициент и число итераций для проверки принадлежности точки к множеству Жюлиа:
c = complex(-0.2, 0.75) P = 200 # размер [2*P+1 x 2*P+1] scale = P / 2 # масштабный коэффициент n_iter = 100 # число итераций для проверки принадлежности к множеству Жюлиа
После этого выполним цикл по множеству точек и те их их, что принадлежат множеству Жюлиа, закрасим в черный цвет:
for y in range(-P, P): for x in range(-P, P): a = x / scale b = y / scale z = complex(a, b) for n in range(n_iter): z = z**2 + c if abs(z) > 2: break else: pygame.draw.circle(sc, BLACK, (x + P, y + P), 0)
Смотрите, когда мы делим текущие координаты (x, y) на масштаб scale, то все значения комплексного числа z у нас пробегают диапазон [-2; 2] по каждой из осей. То есть, мы точки изображения отображаем в комплексную плоскость в квадрат диапазона [-2; 2]. Далее, делаем 100 итераций и если цикл завершается штатно, то есть, модуль точки не превысил порогового значения 2, то делаем вывод, что это точка множества Жюлиа и мы ее закрашиваем черным цветом.
После запуска программы увидим следующее изображение:

Это множество точек для константы
. Если взять другую константу
, то получим другое множество точек:

Таким образом, меняя константы c можно получать самые разные конфигурации множества Жюлиа. И это только один вид функции:


В общем случае можно брать произвольные функции полиномов степени вида:

и получать более сложные виды конфигураций множеств.
Но мы остановимся на этом виде функции и следующим шагом выполним раскраску этого множества для лучшего визуального восприятия. Для этого в цикле формирования точек, внесем следующие изменения:
for y in range(-P, P): for x in range(-P, P): a = x / scale b = y / scale z = complex(a, b) n = 0 for n in range(n_iter): z = z**2 + c if abs(z) > 2: break if n == n_iter-1: r = g = b = 0 else: r = (n % 2) * 32 + 128 g = (n % 4) * 64 b = (n % 2) * 16 + 128 pygame.draw.circle(sc, (r, g, b), (x + P, y + P), 0)
Мы здесь после цикла итераций проверяем, если дошли до конца цикла, значит, точка относится к множеству и по прежнему отображаем ее черным цветом. Иначе, для других точек, не входящих в множество, формируем цвета в зависимости от удаленности точки от границы множества, то есть, в зависимости от значения n. Здесь приведены выражения, которые я подобрал путем «тыка», чтобы получались привлекательные цвета. В итоге, имеем следующее:

Здорово, правда? Можно подобрать и другие константы. Я приведу небольшой их список на языке Python:
#c = complex(-1) #c = complex(-0.2, 0.75) #c = complex(-0.1244, 0.756) #c = complex(-0.1194, 0.6289) #c = complex(-0.7382, 0.0827) c = complex(0.377, -0.248)
Попробуйте и посмотрите, что у вас получится. Мало того, мы легко можем менять масштаб изображения. Если переменную scale установить равной:
scale = P / 1
то изображение станет больше (как бы ближе к наблюдателю):

Это из-за того, что мы пробегаем квадрат [-1; 1] на комплексной плоскости с той же плотностью точек. В результате, как бы рассматриваем это изображение с большей детализацией.
Если нам нужно приблизить масштаб относительно произвольной точки, то для этого достаточно задать переменную с координатами смещения:
scale = P / 0.25 # масштабный коэффициент view = (0, -500) # координаты смещения угла обзора
В циклах учесть это смещение:
for y in range(-P+view[1], P+view[1]): for x in range(-P+view[0], P+view[0]):
И при отображении точки:
pygame.draw.circle(sc, (r, g, b), (x + P - view[0], y + P - view[1]), 0)
Все, теперь, мы можем увеличить и детальнее рассмотреть верхний участок этого множества:

Вот такие изображения можно получать с помощью одной единственной функции с проверкой ее сходимости в различных точках комплексной плоскости. Надеюсь, из этого занятия вы теперь лучше стали понимать что такое множество Жюлиа, как его можно построить и раскрасить. На следующем занятии мы проделаем похожие манипуляции для построения самого известного фрактального множества Мандельброта.
Видео по теме

Фракталы вокруг нас. Как все начиналось

#1. Кривая Коха и снежинка Коха

#2. Рисуем кривую Коха и снежинку Коха

#3. Простая L-система на плоскости

#4. L-система для дракона Хартера-Хайтвея, ковра Серпинского и кривой Гильберта

#5. L-система с ветвлениями. Рисуем деревья и травы

#6. Добавляем параметры в L-систему

#7. Добавляем случайности в L-систему

#8. Добавляем цвет в L-систему

#9. Как вычисляется фрактальная размерность по Хаусдорфу

#10. Системы итерированных функций СИФ
#11. Рандомизированная система итерированных функций

#12. Примеры фракталов, сгенерированных СИФ

#13. Как построить множества Жюлиа

#14. Рисуем множество Мандельброта
© 2023 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Простая L-система на плоскости
На предыдущем занятии мы с вами получили первый опыт рисования фрактала с помощью черепашьей графики на Python. Но каждый раз писать отдельную программу для прорисовки новой фрактальной кривой не лучшее занятие. Правильнее было бы оптимизировать этот процесс, используя универсальный подход к генерации различных фракталов. Именно эта идея положена в основу L-систем, создающие фрактальные изображения.
Вначале мы сделаем такое упрощение. Все команды для черепашки опишем отдельными символами. Обычно, используют следующие обозначения:
Тогда команду для рисования одного сегмента кривой Коха можно записать в виде строки:
Причем, здесь F – это будет одно и то же движение вперед на строго заданное число пикселей, а повороты осуществляться на заданный угол в 60 градусов, так как для формирования кривой Коха нам нужен именно такой угол. У другого фрактала угол может быть другим. В результате, черепашка сначала пройдет вперед, затем, повернет влево на 60 градусов, снова пройдет вперед, повернет вправо на 120 градусов (два символа минус), опять пройдет вперед, повернет влево на 60 градусов и еще пройдет вперед. Получим сгемент ломаной.
Но одной ломаной мало, на каждой новой итерации линейный сегмент также должен превращаться в такую же ломаную. Чтобы это сделать, давайте определим правило: каждый символ F на новой итерации должен заменяться на строку «F+F—F+F»:
Например, для формирования кривой Коха 2-й итерации черепашка должна будет последовательно выполнить команды:

Мало того, саму первую итерацию также можно сформировать по этому же правилу, взяв за основу обычную прямую:

Вот эта первая предельная прямая в теории L-систем назыается инициатором или аксиомой. Таким образом, имея инициатор и правило формирования, мы получаем возможность генерировать описание фрактала на уровне команд черепашьей графики. Давайте реализуем класс, который бы выполнял описанные действия.
Для начала мы пропишем базовый функционал в классе LSystem2D, который и будет представлять простую L-систему на плоскости:
class LSystem2D: def __init__(self, t, axiom, width, length, angle): self.axiom = axiom # инициатор self.state = axiom # строка с набором команд для фрактала (вначале это инициатор) self.width = width # толщина линии рисования self.length = length # длина одного линейного сегмента кривой self.angle = angle # фиксированный угол поворота self.t = t # сама черепашка self.t.pensize(self.width) def draw_turtle(self, start_pos, start_angle): # *************** turtle.tracer(1, 0) # форсажный режим для черепашки self.t.up() # черепашка воспаряет над поверхностью (чтобы не было следа) self.t.setpos(start_pos) # начальная стартовая позиция self.t.seth(start_angle) # начальный угол поворота self.t.down() # черепашка опускается на "грешную землю" # *************** for move in self.state: if move == 'F': self.t.forward(self.length) elif move == '+': self.t.left(self.angle) elif move == '-': self.t.right(self.angle) turtle.done() # чтобы окно не закрывалось после отрисовки
И воспользуемся им, следующим образом:
# ************** чтобы окно появлялось в левом верхнем углу с размерами 1200x600 width = 1200 height = 600 screen = turtle.Screen() screen.setup(width, height, 0, 0) # ************** t = turtle.Turtle() t.ht() # скрываем черепашку pen_width = 2 # толщина линии рисования (в пикселах) f_len = 50 # длина одного сегмента прямой (в пикселах) angle = 60 # фиксированный угол поворота (в градусах) l_sys = LSystem2D(t, "F", pen_width, f_len, angle) l_sys.draw_turtle( (0, 0), 0)
После запуска должны увидеть прямую линию.
Отлично, начало положено. Осталось реализовать метод, который бы генерировал команды для описания фрактальной кривой согласно заданному правилу (или набору правил). Для этого, мы в конструкторе пропишем свойство, хранящее набор правил в виде словаря:
self.rules = {} # словарь для хранения правил формирования кривых
А ниже зададим метод, который будет добавлять новое правило в этот словарь:
def add_rules(self, *rules): for key, value in rules: self.rules[key] = value
Причем, правила будем передавать в виде списков из двух элементов в формате:
Например, для построения кривой Коха, этот список будет таким:
l_sys.add_rules(("F", "F+F--F+F"))
Осталось применить это правило для генерации фрактала. За это будет отвечать метод generate_path:
def generate_path(self, n_iter): for n in range(n_iter): for key, value in self.rules.items(): self.state = self.state.replace(key, value.lower()) self.state = self.state.upper()
В качестве аргумента мы ему передаем число итераций для кривой и, затем, делаем цикл n_iter раз. На каждой итерации во внутреннем цикле перебираем все правила из словаря в формате ключ-значение и в формируемом маршруте (свойстве state) заменяем все найденные ключи на соответствующие значения. Причем, переводим все символы в нижний регистр. Это необходимо, чтобы у нас не было вложенных замен, при использовании нескольких правил. Когда одно правило содержит ключи из другого правила. Поэтому, я реализовал такой трюк – все замены делаются в нижнем регистре, полагая, что ключи всегда будут только в верхнем регистре. После всех замен вновь переводим строку в верхний регистр, как это и должно быть и получаем маршрут для черепашки на текущей итерации. Повторяем эту процедуру n_iter раз и у нас плучается готовая строка с набором необходимых команд.
Теперь у нас все готово для генерации простых фрактальных кривых. Давайте это сделаем. Вначале, конечно же, нарисуем кривую Коха на 4-й итерации. Для этого вызовем метод:
l_sys.generate_path(4)
и установим длину сегмента в 5 пикселей:
f_len = 5
После запуска увидим следующую картину:

Но чем хороша L-система, это то, что теперь у нас есть универсальный инструмент для построения большого числа разных фракталов. Например, чтобы получит снежинку Коха, достаточно инициатор определить в виде равностороннего треугольника:
l_sys = LSystem2D(t, "F--F--F", pen_width, f_len, angle)
Видите, как это просто! Нам не пришлось вносить изменения на уровне команд, а только поменять один параметр.
Что еще можно изобразить такой L-системой? Например, такую кривую:
angle = 90 axiom = "F-F-F-F" l_sys = LSystem2D(t, axiom, pen_width, f_len, angle) l_sys.add_rules(("F", "F+FF-FF-F-F+F+FF-F-F+F+FF+FF-F"))
С числом итераций 2:
l_sys.generate_path(2)
Увидим следующее построение:

Уже неплохо. Однако, не все кривые можно построить непрерывно перемещая черепашку. Иногда ей нужно перескакивать с места на место. Для этого добавим еще одну команду:
S – переместиться вперед без рисования пути
Для этого в метод draw_turtle() добавим еще одну проверку:
elif move == 'S': self.t.up() self.t.forward(self.length) self.t.down()
И это все. Теперь можно генерировать еще более сложные фракталы. Например, такой «ковер»:
angle = 90 axiom = "F+F+F+F" l_sys = LSystem2D(t, axiom, pen_width, f_len, angle) l_sys.add_rules(("F", "F+S-FF+F+FF+FS+FF-S+FF-F-FF-FS-FFF"), ('S', 'SSSSSS')) l_sys.generate_path(2)

Я думаю, вы уловили принцип использования L-систем для формирования и отображения разнообразных фрактальных кривых. Но то что мы сделали – это лишь первый шаг. На следующем занятии мы немного усложним алгоритм и сможем получать кривые еще более сложных форм.
Видео по теме

Фракталы вокруг нас. Как все начиналось

#1. Кривая Коха и снежинка Коха

#2. Рисуем кривую Коха и снежинку Коха

#3. Простая L-система на плоскости

#4. L-система для дракона Хартера-Хайтвея, ковра Серпинского и кривой Гильберта

#5. L-система с ветвлениями. Рисуем деревья и травы

#6. Добавляем параметры в L-систему

#7. Добавляем случайности в L-систему

#8. Добавляем цвет в L-систему

#9. Как вычисляется фрактальная размерность по Хаусдорфу

#10. Системы итерированных функций СИФ
#11. Рандомизированная система итерированных функций

#12. Примеры фракталов, сгенерированных СИФ

#13. Как построить множества Жюлиа

#14. Рисуем множество Мандельброта
© 2023 Частичное или полное копирование информации с данного сайта для распространения на других ресурсах, в том числе и бумажных, строго запрещено. Все тексты и изображения являются собственностью сайта
Как построить фрактал в python

Множество Мандельброта стало известно в середине 1980-х годов при демонстрации компьютерной графики, когда персональные компьютеры стали достаточно мощными, чтобы построить и отобразить множество в высоком разрешении[5].
- Пробитие уровня предыдущего фрактала называется прорывом покупателей в случае, если цена поднимается выше предыдущего фрактала, направленного вверх.
- Отдельно нужно сказать о попытках применения подобных индикаторов в автоматических советниках.
- Можно как открыть массу убыточных сделок, так и пропускать хорошие точки входа.
- Однако около ста лет назад математики начали исследовать, что происходит с этими последовательностями, если использовать в них комплексные числа, а не просто прямую действительных чисел.
- Так для покупок, ставим Buy Stop выше (от 2 до 4 пунктов) максимума второй по отношению к фрактальной свечи.
В некоторых случаях члены последовательности не сходятся к единственной точке – вместо этого они образуют цикл из нескольких значений-точек, как треугольник. Как видите, последовательность сходится, пока x0 лежит внутри единичной окружностиснаружи единичного квадратана оси х (окружность с радиусом 1, центр в начале координат). Если x0 находится между –1 и 1, последовательность сходитсярасходится.
Как пользоваться в терминале MT4 индикатором Вильямса – Fractals, разработанным на основе Фрактала Мандельброта?
Таким образом, свои фрактальные исследования он начинает применять к цене, и сегодня его методика широко используется для проведения анализа фондовых бирж и валютных рынков. Эти процессы, очень подробно описаны в трудах Бенуа Мандельброта. Сегодня мы расскажем, что же собой представляет индикатор Фрактал и как пользоваться данным инструментом.
Индикатор Фракталы Вильямса достаточно далеко от классической математической теории, и по факту, представляет собой просто очередной ценовой экстремум на участке 5 и больше баров. Это обычные максимумы/минимумы, торгуемые на коррекциях и откатах – для этого необходимо открывать позицию в сторону общей линии тренда. Однако, появляются они на графике достаточно часто, это не сказывается положительно на надежности сигналов, но при правильном использовании приносят стабильную прибыль. Фракталы в качестве технического инструмента первым использовал Билл Вильямс, в то время это вызвало массу споров об их эффективности на финансовых рынках. Тем более автор использовал большое количество специальных терминов, таких как аттрактор, что не добавляло популярности инструменту среди начинающих. Поскольку данный индикатор настроен на 5 свечей автоматически, то на экране фракталы появляются достаточно часто.
История множества Мандельброта[править править код]
В 1985 году множество Мандельброта появился на обложке журнала Scientific American, и с тех пор оно стало одной из самых узнаваемых математических форм в мире. Вы можете найти его на футболках, в музыкальных клипах и в качестве заставок, на него ссылаются во многих популярных книгах и фильмах. В каждом круге последовательности имеют орбиты с разным количеством циклов, причем, чем меньше круг, тем больше циклов в орбитах. Размер этих орбит тесно связан с логистической картой, важной концепцией в теории хаоса.
Результаты не внушают оптимизма – пока не создан алгоритм, который может заменить визуальный анализ, особенно неидеальных конструкций, которых на реальном рынке больше 50%. Можно как открыть массу убыточных сделок, так и пропускать хорошие точки входа. Также есть понятие размерности от больших таймфреймов к младшим, т.е. Использование фрактальных конструкций имеет смысл только сверху-вниз. Максимум/минимум, например, D1 будет подобной точкой и на меньших промежутках. Верхние фракталы считается устойчивым, если длина отрезка между основаниями левого и правого крайних баров меньше, чем между основаниями и вершиной.
Индикатор Фрактал дает возможность анализировать рынок по реальной ситуации, не обращаясь к историческим данным – достаточно всего пяти последних баров и понимания симметричности любых ценовых колебаний. Индикатор «Фрактал» уже не первый год успешно применяется многими трейдерами для торговли на Форексе. Это технический индикатор, направленный на определение впадин и вершин графика. Он подбирает подобные множества данных, которые и позволяют вам зарабатывать. Но необходимо понимать, что успешная торговая система не может быть построена только лишь на одном индикаторе.
На графике фракталы имеют значения High и Low и отмечены стрелками вверх или вниз. Билл Вильямс советовал использовать фракталы в стратегиях, которые базируются на пробое важных ценовых уровней. Движение цены выше или ниже хотя бы на один пункт от уровня предыдущего фрактала, по мнению автора этого индикатора, уже говорит о пробитии этого уровня ценой. Сигналы технического индикатора Fractals необходимо отфильтровывать с помощью технического индикатора Аллигатор. Другими словами, не следует заключать сделку на покупку, если фрактал находится ниже Зубов Аллигатора, и не следует заключать сделку на продажу, если фрактал находится выше Зубов Аллигатора.
Администрация InfoFx.ru не несет ответственности за различного рода потери или ущерб, который может возникнуть вследствие использования информации находящейся на данном сайте. Так, когда тренд восходящий наблюдается частое обновление всех бычьих фракталов, а при нисходящей тенденции чаще обновятся медвежьи фракталы. Наличие https://fxsteps.info/chto-vy-znaete-o-price-action-strategija/ на графиках фракталов, значительно упрощает обнаружение минимумов и максимумов, через которые строятся трендовые линии. Поэтому, расписывать досконально все математические алгоритмы мы не будем. В итоге у создателя получился индикатор Фрактал, позволяющий обнаруживать на графиках цен в терминалах МТ4 впадины и вершины.
Чёрно-белое множество, то которое получил Мандельброт
Таким образом, имеем два основания для верхней (соответственно две вершины для нижней) модели и центральную вершину/дно. Исходя из принципа построения, фрактал всегда будет запаздывать на 2 и более свечи и ничего с этим не поделать. На истории индикатор выглядит очень эффективно, а на деле, когда появляется сигнал цена уже значительно отличается от сигнальной. О наличии консолидации (флета), говорит невозможность ценой в очередной раз пробития предыдущего фрактала. Для подтверждения такого сигнала следует дождаться пока не сформируется противоположный фрактал.
Перспективы науки велики и безграничны, но уже сегодня фрактальная геометрия успешно используется на благо людям. Современные беспроводные средства связи (да-да, и ваш мобильный телефон не исключение!) применяют антенны и микросхемы, сконструированные по ветвящемуся фрактальному принципу. Это позволяет многократно увеличить скорость и объём передачи данных. Вся информация, находящаяся на данном сайте, не является рекомендацией или советом к открытию сделок, она предоставляется лишь в качестве общих данных, относительно ситуации на валютном рынке.
Где и как применять данную фрактальную теорию?
Это структура фракталов — основа построения нашего столь многообразного мира. Нет в природе формы, будь то живая или неживая материя, которая бы не имела к ним отношения. Горы, реки, облака, наконец, живые существа созданы Творцом по одному принципу, который так долго искала и не могла найти наука.
Чтобы сделать его цветным, можно, например, каждую точку не из множества красить в цвет, соответствующий номеру итерации, на котором её последовательность вышла за пределы круга. Однако около ста лет назад математики начали исследовать, что происходит с этими последовательностями, если использовать в них комплексные числа, а не просто прямую действительных чисел. Их открытия были одними из самых удивительных и красивых результатов во всей математике.
Как пользоваться в торгах на Форекс индикаторами на основе фракталов?
Так что, дорогие россияне, наш герб включает в себя самый настоящий фрактал, возможно, как символ бесконечности нашей истории и самовозрождения подобно мифическому фениксу. Таинственные закономерности фракталов не оставили равнодушными и другие социальные институты. Цикличность различных общественных и природных процессов была открыта давно, но до сих пор постигалась на ощупь, практически вслепую. Экономика, социология, климатология — далеко не полный перечень областей, где теория фракталов, а точнее неких космических повторяющихся ритмов, которые следует изучать, может найти своё применение.
После того, как сигнал фрактала сформирован и имеет силу, что определяется его позицией вне Пасти Аллигатора, он остается сигналом до тех пор, пока не поражается, либо до той поры, пока не возникает более свежий сигнал фрактала. В классической интерпретации, Билл Вильямс советует фильтровать торговые сигналы, подаваемые фракталами, с помощью индикатора «Аллигатор». Так, для открытия позиции на покупку, необходимо, чтобы был пробит фрактал, находящийся выше красной линии (так называемые «Зубы аллигатора»). Автор стратегии советовал входить в рынок сразу после пробития фрактала вверх или же с помощью отложенного ордера BuyStop. Вход в рынок на продажу происходит в случае пробития фрактала, находящегося ниже красной линии. Основным недостатком инструмента является запаздывание – любая модель не будет считаться действующей до появления двух разворотных баров.
Спустя всего несколько часов после знаменитого парада на Красной площади затонул санитарный теплоход «Армения», перевозивший из Севастополя в Туапсе тысячи раненых солдат и мирных жителей. Даже по самым скромным подсчётам, число жертв катастрофы втрое превысило погибших на «Титанике». До недавнего времени никто точно не знал ни места, ни причины гибели судна. И уж конечно, фантастическую красоту фракталов по достоинству оценили художники, породив целое направление компьютерной графики.
Фракталы на Python. Пошаговое руководство
Привет, Хабр! Сегодняшний пост про фракталы попался в рамках проработки темы Python, в частности, Matplotlib. Последуем примеру автора и предупредим, что в посте много тяжелой анимации, которая может даже не работать на мобильном устройстве. Зато как красиво.

Всем приятного чтения
Фракталы прекрасны. Они выстраиваются в соответствии с очень сложным паттерном и сохраняются без искажения при любом увеличении! В этой статье мы рассмотрим, как можно с легкостью начертить фракталы нескольких видов, воспользовавшись инструментом под названием L-Systems и модулем Turtle для Python, чтобы выполнить пошаговое вычерчивание.
В этой статье мы не будем чрезмерно вдаваться в технические детали; вместо этого я ограничусь кратким введением, покажу много анимированных примеров и код, при помощи которого вы сможете сами сгенерировать такой пример. Если желаете пропустить теорию и только посмотреть анимацию, сразу переходите к примерам. Кроме того, в конце я укажу несколько ресурсов, как по написанию кода, так и по базовой математике, которые вы, возможно, захотите исследовать.
Что такое фрактал?
Для начала давайте дадим «нестрогое» определение фрактала. В принципе, фрактал — это геометрическая фигура, демонстрирующая одни и те же свойства независимо от степени увеличения.
Это определение небезупречно, поэтому вот более точное с сайта Math World:
Фрактал – это объект или величина, демонстрирующие самоподобие (в формальном смысле) в любых масштабах. Объект демонстрирует при разных масштабах не идентичные структуры, но на всех уровнях фрактала должны проявляться структуры одного и того же «типа». В таком случае график, откладываемый в системе координат с логарифмическим масштабом, где по осям отсчитываются величина и масштаб, то график представляет собой прямую линию с наклоном, отражающим размерность фрактала. — Math World
Как чертить фракталы при помощи Python?
Как правило, отрисовка фракталов сложна, так как глубинная природа фракталов определяется концепцией рекурсии. Говоря о графиках и их вычерчивании, мы обычно считаем, что они образованы пикселями или векторами, но количество пикселей или векторов всегда ограничено, а фракталы по определению бесконечно рекурсивны. Таким образом, попытавшись нанести фрактал на координатную сетку, мы в какой-то момент должны будем остановиться, и именно поэтому мы в данном случае говорим об «итерациях». На каждой итерации фрактал становится все сложнее, и в какой-то момент становится невозможно отличить две его итерации, следующие друг за другом (такой момент наступает, когда изменения происходят на уровне, сравнимом с размером пикселя). Здесь логично остановиться, но, как правило, форма фрактала вырисовывается быстрее, и остановиться можно еще раньше.
Два подобных примера – квадратный остров Коха, чья структура четко вырисовывается после трех итераций, и дракон Картера-Хейтуэя, для построения полной структуры которого достаточно 8 итераций. Необходимое количество итераций сильно зависит от конкретного фрактала, с которым мы работаем.
Разумеется, существует множество библиотек на Python для построения графиков, среди которых наиболее популярна Matplotlib, но они обычно рассчитаны на нанесение статистических данных и вычерчивание хорошо известных графиков. В частности, Matplotlib содержит некоторые низкоуровневые конструкции, при помощи которых можно строить фракталы, но на этот раз мы сосредоточимся на незаслуженно малоизвестном модуле стандартной библиотеки, который называется Turtle.
Модуль Turtle
В документации Python читаем: «графика Turtle – популярный инструмент для первого знакомства детей с программированием. Он входил в состав оригинального языка программирования Logo, разработанного Уолли Фёрзегом и Сеймуром Пейпертом в 1966 году.»
Суть заключается в том, что черепаха по умолчанию распознает 3 команды:
- Ползти вперед
- Повернуть влево на угол
- Повернуть вправо на угол
- Отключить запись
- Включить запись
L-система – это способ представления рекурсивных структур (например, фракталов) в виде строки символов и многократной перезаписи такой строки. Опять же, дадим формальное определение:
Система Линденмайера, также известная как L-система, это механизм перезаписи строк, который может использоваться для генерации фракталов с размерностью от 1 до 2 — Math World
Поняв, что такое L-система, мы сможем создавать рекурсивные структуры, но прежде давайте разберемся, какие компоненты нам для этого понадобятся. В каждой L-системе есть:
- Алфавит: множество символов, которые будет использовать L-система.
- Аксиома: исходная строка для генерации.
- Набор инструкций создания строк: эти инструкции описывают, как каждый символ должен заменяться на следующей итерации.
Учитывая, что мы собираемся использовать Turtle для построения графиков и L-системы для представления того, что собираемся наносить на график, нам необходимо создать взаимосвязь между ними.
Поскольку в Turtle мы располагаем только теми командами, что перечислены выше, присвоим каждой из них символ; из этих символов и будет состоять алфавит.
- F: ползти вперед
- +: повернуть вправо
- -: повернуть влево
Теперь давайте перейдем к примерам!
Анимированные примеры
Следующие примеры были взяты в Интернете из нескольких общедоступных источников, и я решил портировать их на Python при помощи модуля Turtle, центрировать их, раскрасить и предоставить способ экспорта в векторный формат.
ВНИМАНИЕ: предлагаемые анимации достаточно велики, рекомендуется смотреть их лишь с хорошим интернетом. Код Repl может не работать, так как потребляет ваши ресурсы, и с отображением фракталов на мобильных устройствах возможны проблемы.
Внимание: Skulpt использует для рендеринга и создания анимации ВАШ БРАУЗЕР, так что при подвисании, лагах или любом странном поведении обычно достаточно просто заново воспроизвести анимацию или перезагрузить страницу. На мобильном устройстве может не работать.
Примеры даны в порядке усложнения (на мой субъективный взгляд), так что самое интересное – в конце.
axiom = "F--F--F" rules = iterations = 4 # TOP: 7 angle = 60
axiom = "F+F+F+F" rules = iterations = 2 # TOP: 4 angle = 90
axiom = "F+F+F+F" rules = <"F":"FF+F++F+F">iterations = 3 # TOP: 6 angle = 90
axiom = "F--F" rules = iterations = 4 # TOP: 6 angle = 90
axiom = "F-F-F-F" rules = iterations = 4 # TOP: 6 angle = 90
axiom = "F" rules = iterations = 10 # TOP: 16 angle = 45
axiom = "YF" rules = iterations = 1 # TOP: 10 angle = 60
axiom = "FXF--FF--FF" rules = iterations = 7 # TOP: 8 angle = 60
axiom = "F+F+F+F" rules = iterations = 3 # TOP: 5 angle = 90
axiom = "F+F+F+F" rules = iterations = 3 # TOP: 4 angle = 90
axiom = "F+F+F+F" rules = iterations = 2 # TOP: 4 angle = 90
axiom = "F+F+F+F" rules = iterations = 3 # TOP: 6 angle = 90
axiom = "F++F++F++F++F" rules = <"F":"F++F++F+++++F-F++F">iterations = 1 # TOP: 5 angle = 36
axiom = "F+F+F+F" rules = iterations = 3 # TOP: 3 angle = 90
axiom = "FX" rules = <"X":"X+YF++YF-FX--FXFX-YF+", "Y":"-FX+YFYF++YF+FX--FX-Y">iterations = 4 # TOP: 6 angle = 60
axiom = "F+XF+F+XF" rules = iterations = 4 # TOP: 8 angle = 90
axiom = " -X--X" rules = iterations = 3 # TOP: 9 angle = 45
axiom = "YF" rules = iterations = 2 # TOP: 3 angle = 90
axiom = "LFL-F-LFL" rules = iterations = 0 # TOP: 8 angle = 90
axiom = "L" rules = iterations = 8 # TOP: 9 angle = 90
axiom = "X" rules = iterations = 4 # TOP: 6 angle = 90
axiom = "F" rules = iterations = 2 # TOP: 5 angle = 90
axiom = "F+F+F+F" rules = <"F":"F+FF++F+F">iterations = 3 # TOP: 6 angle = 90
axiom = "F+F+F" rules = iterations = 2 # TOP: 9 angle = 120
axiom = "FX" rules = iterations = 8 # TOP: 16 angle = 90
axiom = "F" rules = iterations = 5 # TOP: 10 angle = 120
axiom = "FX+FX" rules = iterations = 6 # TOP: 16 angle = 90
axiom = "FX+FX+FX" rules = iterations = 7 # TOP: 15 angle = 90
Все вышеприведенные примеры были получены при помощи одного и того же кода, и при работе над ними возникли некоторые сложности (например, как удержать фрактал в центре, насколько это возможно), работа с цветом, инверсией, смещениями, а также обеспечение быстрого экспорта в векторный формат. Здесь я демонстрирую вам лишь простейшую версию.
Данная версия выводит фракталы в черно-белом виде и не оснащена функционалом для экспорта
import turtle def create_l_system(iters, axiom, rules): start_string = axiom if iters == 0: return axiom end_string = "" for _ in range(iters): end_string = "".join(rules[i] if i in rules else i for i in start_string) start_string = end_string return end_string def draw_l_system(t, instructions, angle, distance): for cmd in instructions: if cmd == 'F': t.forward(distance) elif cmd == '+': t.right(angle) elif cmd == '-': t.left(angle) def main(iterations, axiom, rules, angle, length=8, size=2, y_offset=0, x_offset=0, offset_angle=0, width=450, height=450): inst = create_l_system(iterations, axiom, rules) t = turtle.Turtle() wn = turtle.Screen() wn.setup(width, height) t.up() t.backward(-x_offset) t.left(90) t.backward(-y_offset) t.left(offset_angle) t.down() t.speed(0) t.pensize(size) draw_l_system(t, inst, angle, length) t.hideturtle() wn.exitonclick()
Пояснение кода
import turtle
Сначала нужно импортировать модуль Turtle
def create_l_system(iters, axiom, rules): start_string = axiom if iters == 0: return axiom end_string = "" for _ in range(iters): end_string = "".join(rules[i] if i in rules else i for i in start_string) start_string = end_string return end_string
Затем потребуется сгенерировать L-систему, которая будет представлять собой набор инструкций для черепахи. Определяем функцию create_l_system , которая получает количество итераций, аксиому и правила построения. Она начинает работу с аксиомы и использует вспомогательную переменную end_string , если итерация равна 0, то она вернет аксиому, поскольку некоторые фракталы можно наносить и нулевыми итерациями. В данном случае предполагается, что правила имеют вид словарей, поэтому каждый ключ уникален, представляет собой символ, а значение указывает, что и чем нужно заменить. Так мы объединяем все замены для каждого символа и в итоге получаем строку для следующей итерации.
def draw_l_system(t, instructions, angle, distance): for cmd in instructions: if cmd == 'F': t.forward(distance) elif cmd == '+': t.right(angle) elif cmd == '-': t.left(angle)
Затем определяем draw_l_system , которая принимает черепаху, набор инструкций (вывод L-системы), угол для поворота влево или вправо и длину каждой отдельной линии. Она состоит из простой структуры elif для каждой из ранее определенных команд.
def main(iterations, axiom, rules, angle, length=8, size=2, y_offset=0, x_offset=0, offset_angle=0, width=450, height=450): inst = create_l_system(iterations, axiom, rules) t = turtle.Turtle() wn = turtle.Screen() wn.setup(width, height) t.up() t.backward(-x_offset) t.left(90) t.backward(-y_offset) t.left(offset_angle) t.down() t.speed(0) t.pensize(size) draw_l_system(t, inst, angle, length) t.hideturtle() wn.exitonclick()
Наконец, поговорим о функции main , которая принимает все параметры, необходимые для генерации L-систем, а также y_offset , x_offset , offset_angle , width и height . Три первых описывают смещение черепахи, это необходимо просто для позиционирования графика на холсте так, как нам того хочется.
Функция сначала генерирует набор инструкций и сохраняет их в inst, затем инициализирует черепаху и экран и ставит черепаху в определенную точку, затем наносит график в соответствии с инструкциями и ожидает клика, чтобы закрыться.
Особые соображения
Как я упоминал выше, здесь оставлено множество ограничений. Во-первых, мы не предусмотрели для черепахи возможность двигаться без отрисовки; для этого потребовался бы еще один символ. Нет здесь и символа для отступления назад, и для запоминания предыдущих позиций. Они не требовались для всех фракталов, рассмотренных выше, но обязательны для некоторых других (например, фрактальных деревьев).
Дополнительные ресурсы
В Интернете множество ресурсов по фракталам, где они рассматриваются как с точки зрения программирования, так и с точки зрения математики. Следующие два показались мне особенно интересными: 3Blue1Brown (математика) и CodingTrain (код).
Статья написана под впечатлением поста с Math World и статьи Пола Бурка.
