Рисуем фракталы с помощью PHP и Cairo. Часть 3. Фракталы на комплексной плоскости

В данной статье мы познакомимся с различными видами комплексных фракталов и способами их отрисовки с помощью библиотек GTK и Cairo.

Почему эти фракталы называются комплексными? Очень просто: для их получения используются комплексные числа.

Понятие комплексного числа появилось в результате развития теории решения квадратных уравнений с отрицательным дискриминантом. Математикам пришлось освоить новую идею о том, что некоторые величины возведённые в чётную степень могут давать отрицательные значения. Так в математику вошла мнимая единица, квадрат которой даёт минус единицу. Что же представляет собой комплексное число?

Согласно стандартному определению: комплексное число это выражение вида

в котором a и b принадлежат множеству действительных чисел, а i это мнимая единица. Говоря простым языком: комплексное число это сумма двух чисел — вещественного (a) и мнимого (b).

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

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

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

Архитектура приложения

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

  • Координаты центра отрисовки фрактального изображения
  • Масштаб отрисовки
  • Тип фрактала

Данные параметры можно передать через созданные поля ввода. Соответственно, нам нужно будет также создать кнопку для запуска процесса обновления. Поэтому исходный код drawing_window.php примет следующий вид:

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

Метод получения фрактального изображения основан на итерировании одной и той же комплексной формулы. По сути это рекурсивный вызов функции с параметром полученным на предыдущем шаге. Но так как мы уже постигли кое-что относительно рекурсии, мы будем использовать именно итерации, так как в этом случае код будет довольно простым и эффективным. Для каждого отдельного вида фрактала формула будет своя, но в то же время она будет общей для всего множества пикселов принадлежащих данному виду фрактала. И в то же время алгоритм прохода по всем пикселам изображения (всей комплексной плоскости) будет общим для всех типов фракталов и мы реализуем его в единственном экземпляре.

Итак всё что мы хотим это пройтись по всему множеству точек фрактала, посчитать в них значения интенсивности, и далее сделать небольшое улучшение полученного изображения, а затем отобразить его в нашем окне. Думаю будет неплохо использовать случайным образом сгенерированные градиенты и альфа-смешивание, чтобы можно было увидеть красоту фрактала «в цвете».

Теперь мы можем приступать к написанию основного класса нашего приложения fractal_drawer.php.

Так как в функции onDraw мы используем один и тот же метод getValue, то будет разумным, создать отдельный абстрактный класс интерфейса, общий для всех видов фракталов. Мы назовём его FractalSet и создадим для него отдельный файл fractal_set.php. Это позволит нам удобно обращаться с фракталами в не зависимости от их конкретного вида. В классе будет всего два метода, поэтому он будет выглядеть достаточно лаконично:

Теперь всё готово для того, чтобы приступить к рассмотрению отдельных видов фракталов.

Фрактал Мандельброта

Итак, в предыдущих статьях мы уже встречались с данным видом фрактала. Вы даже можете увидеть его изображение на одной из фотографий, которые были приведены в статье . Этот фрактал является иконой фрактальной графики. Он бесконечно сложен и в то же время очень красив и элегантен. А с точки зрения математики алгоритм его получения весьма прост и определяется формулой:

Здесь n это номер итерации, а с — произвольная константа (обычно за неё принимают текущие координаты на комплексной плоскости). Начальные условия у нас такие:

Итерирование данной формулы при заданном значении константы даёт нам величину интенсивности по номеру итерации, при условии что получаемая точка не выходит дальше области ограниченной окружностью радиуса 2. Этот алгоритм реализуется в следующем коде:

В нашем случае, запуск fractal_drawer.php приведёт к созданию самоподобной красоты:

Существуют различные вариации данного вида фрактала. Особенно изысканным в среде дизайнеров считается вариант имеющий название Buddhabrot и напоминающий сидящего в позе лотоса медитирующего будду. Получить его значительно труднее, поэтому я предлагаю выполнить это в качестве упражнения, которое расширит ваше сознание, подобно тому как это делал сам будда.

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

Фрактал Жюлиа

Начальные условия:

Здесь подход немного отличается от представленного выше. Теперь мы используем константу как константу в том смысле, что её значение не будет меняться. А итерации мы начнём с той точки, которая задана через параметры метода.

У меня получился такой вариант:

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

Фрактал Ньютона

Вид функции f(z) может быть любой, в частности мы будем использовать следующую функцию:

Здесь функция в знаменателе это производная от функции f(z), то есть

И вот здесь начинается самое интересное, потому как ранее мы использовали сравнительно простые формулы из теории комплексных чисел. Так вот, для того, чтобы построить фрактал Ньютона, нам нужно использовать операцию возведения в третью степень, а так же деление. Это может быть сделано несколькими способами, но чтобы не усложнять себе жизнь громоздкими формулами, мы воспользуемся библиотекой Math_Complex, доступной для скачивания из официального репозитория php. Вы можете установить её с помощью пакетного менеджера pear или скачать новую версию с github’а. Ну а я просто покажу вам как её использовать для наших целей:

Конечно всё это не эффективно с точки зрения производительности вычислений, потому как под каждой из комплексных операций скрывается очень много ненужных действий, которые можно сократить если вы знаете комплексную математику. В крайнем случае вы можете использовать пакеты символьной алгебры, такие как Maxima или Wolfram Alpha. Это весело, но всё же знание математики необходимо, если вы хотите создавать по-настоящему эффективные приложения.

Насладимся же ещё одним видом прекрасного фрактала…

Следующим примером, мы рассмотрим фрактал Nova. Этот фрактал отдалённо напоминает нам свет далёкой звезды, манящей и непостижимой… Как говорил великий Иммануил Кант:

Две вещи наполняют душу всегда новым и все более сильным удивлением и благоговением, чем чаще и продолжительнее мы размышляем о них — это звездное небо надо мной и моральный закон во мне

Фрактал Nova

Удивителен факт, что наши тела состоят атомов рождённых в недрах звёзд. Ещё более удивительно, что элементы без которых мы не можем жить являются посмертным даром звёзды, завершившей цикл своей эволюции и вспыхнувшей в виде сверхновой. Выражаясь поэтически: жизнь и смерть неразрывно связаны между собой, и нечто, умирая, даёт возможность жизни продолжиться в бесконечность…

Данный фрактал как никакой другой содержит в себе аллюзию к вечности

И ещё я бы хотел рассмотреть один вид фрактала, о котором я не знаю решительно ничего, кроме того, что он напоминает мне дерево Пифагора.

Фрактал Глина

Подобный фрактал уже встречался нам в статье про основы фрактальной графики. Здесь же он возникает в результате применения итераций над функцией комплексной переменной. То есть здесь дискретный и аналитический миры встречаются и крепко пожимают друг другу руки… или ветви, как там принято у деревьев… Вообщем настоящая пифагорейская гармония, как и должно быть, так вот. Код его предельно прост и не нуждается в комментариях:

Если немного изменить масштаб, то можно увидеть здесь и другую философскую вещь. А именно, что очертания набора «фрактального леса» напоминает по форме обыкновенное семя, которое по сути содержит в себе потенцию порождения как отдельного дерева, так и обширного леса. Иногда простое изменение точки зрения позволяет видеть более упорядоченную картину, что называется «видеть лес за деревьями». Данная способность является неотъемлемым признаком высокоразвитого интеллекта. Так что занятие над фракталами пойдёт на пользу вашему интеллекту. В качестве упражнения я предлагаю разобраться со следующим видом фрактала самостоятельно.

Фрактал Rational map

Перед вами исходный код этого фрактала:

Попробуйте сделать так, чтобы этот фрактал выглядел так же красиво, как и все остальные приведённые выше. Подсказка: потребуется сделать изменения в коде, чтобы получить более качественное изображения, потому как в данном коде содержится неявная ошибка, которая не является критической, но всё же может быть устранена.

И ещё, наверное вы заметили, что порой процесс генерации фракталов происходит очень медленно и вызывает замирания пользовательского интерфейса. Я предлагаю вам подумать о том, как обойти это.

Заключение

Что ж и на этом цикл статей по фрактальной графике временно приостанавливается (помните, что фракталы это бесконечная тема). Надеюсь вам было интересно, ну а дальше нас ждёт что-то совершенно особенное… приключение… и об этом в следующей статье, удачи!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.