Как сделать фрактал онлайн
В этой статье мы узнаем что такое фракталы и как рисовать их на PHP используя GTK и Cairo.
Немного о фракталах. Интересные факты
Галактики, рельефы планет, океанские волны, облака и молнии, реки, формы растений и животных, и даже человеческое тело можно рассматривать как фракталы…
Библиотека векторной графики Cairo
Итак, мы начинаем рассмотрение основ фрактальной графики на PHP. В нашей работе мы будем использовать графическую библиотеку Cairo , предназначенную для отрисовки векторной графики. Эта библиотека написана на языке C и может быть использована в связке с такими языками как C++, Python и др.
Данная библиотека обладает тремя существенными преимуществами, обеспечивающими её популярность в среде open source:
- открытый исходный код
- переносимость графического кода между различными платформами
- качественная отрисовка векторной графики
Мы так же будем использовать фреймворк GTK , чтобы иметь возможность взаимодействовать с нашим кодом через графический интерфейс и просматривать получившиеся изображения.
Создание окна GTK. Подготовительный этап
Для начала нам придётся создать класс, который будет отвечать за создание окна. Мы назовём его FractalDrawingWindow и унаследуем его от базового класса GtkWindow , который входит во фреймворк GTK. Это позволит нам работать с оконной системой нашей операционной системы и отображать сгенерированные изображения фракталов внутри неё.
abstract class FractalDrawingWindow extends GtkWindow
// глубина рекурсии создаваемого фрактального изображения (по умолчанию)
protected $recursionDepth = 5;
public function FractalDrawingWindow()
parent::__construct(); // здесь мы вызываем конструктор базового класса,
// для успешной инициализации окна
$this->set_title($this->getName()); // устанавливаем название окна
// по имени фрактала
// устанавливаем корректный способ выхода из окна
$this->connect_simple('destroy', array('gtk', 'main_quit'));
$drawingArea = new GtkDrawingArea(); // создаём область для рисования
// устанавливаем функцию отображения фрактала для данной области рисования
// добавляем созданную область в наше окно
// устанавливаем размер окна
$this->set_default_size(640,480); // по ширине и высоте
// устанавливаем позицию окна на экране
// включаем отображение окна
$this->show_all(); // здесь начинается запуск алгоритма отрисовки
// и отображения фрактала
// функция экспозиции фрактала
public function onExpose($darea, $event)
$context = $darea->window->cairo_create(); // создаём Cairo-контекст для отрисовки
$this->onDraw($context); // отрисовываем конкретный вид фрактала
// функция установа глубины рекурсии
public function setRecursionDepth($recursionDepth)
// здесь мы ограничиваем глубину рекурсии для избежания segmentation fault
if($recursionDepth >= 0 && $recursionDepth
// мы используем чистые абстрактные методы, чтобы
abstract public function getName(); // определить названия фракталов
abstract protected function onDraw($context); // и методы их отрисовки
Рисуем фракталы с помощью PHP и Cairo
Теперь мы можем приступать к рассмотрению конкретных видов фракталов и способов их рисования. И начнём мы с фрактала, который получил название в честь немецкого математика, Георга Кантора.
Канторова пыль
Ashes to ashes, dust to dust
Фраза из английской похоронной службы, часто используемая для обозначения фатальной неизбежности конца.
Рассмотрим следующий код:
include 'drawing_window.php'; // здесь мы подключаем файл с ранее созданным
// классом для работы с окнами GTK
// мы создаём класс по конкретному виду фрактала и унаследуем его от класса
// FractalDrawingWindow, капсулирующего функции для работы с оконной системой
class CantorDust extends FractalDrawingWindow
// здесь мы определяем функцию, которая будет отображаться в названии окна
public function getName()
return "Cantor dust fractal";
// здесь мы определяем метод отрисовки фрактала
protected function onDraw($context)
// устанавливаем основной цвет для отрисовки
$context->setSourceRgb(0.5, 0.5, 0.5);
// запускаем рекурсивную функцию отрисовки фрактала "Канторова пыль"
$this->draw($context,$this->recursionDepth, 0, 0, $this->get_size()[0], floatval($this->get_size()[1]) / $this->recursionDepth);
// рекурсивная функция отрисовки
public function draw($context,$level, $posX, $posY, $sizeX, $sizeY)
// в параметрах мы передаём начальные позиции по оси X и Y и размеры элементов для каждого шага рекурсии
// по достижении установленной глубины рекурсии, производим выход из функции отрисовки
// вычисляем новый размер и положение элемента по оси X
$newSizeX = $sizeX / 3;
$newPosX = $posX + 2 * $newSizeX;
// рисуем левый прямоугольник
$context->rectangle($posX,$posY,$newSizeX,$sizeY); // устанавливаем параметры
$context->fill(); // делаем заливку выделенным цветом, уставновленным ранее в методе onDraw()
// рисуем правый прямоугольник
$context->rectangle($newPosX,$posY,$newSizeX,$sizeY);
// запускаем отрисовку следующего уровня рекурсии
$this->draw($context, $level - 1, $posX, $posY + $sizeY, $newSizeX, $sizeY); // слева
$this->draw($context, $level - 1, $newPosX, $posY + $sizeY, $newSizeX, $sizeY); // и справа
$fractal = new CantorDust(); // создаём объект класса для нашего фрактала
$fractal->setRecursionDepth(15); // устанавливаем глубину рекурсии
Gtk::main(); // запускаем наш фреймворк в работу
После запуска этого кода мы увидим что-то вроде:
Здесь мы используем свойство рекурсии, о котором мы говорили ранее в предыдущих статьях . Это свойство позволяет сделать наш код наглядным и простым и сфокусироваться на самой отрисовке. Алгоритм отрисовки достаточно прост: мы берём точку слева и рисуем прямоугольник в треть длины всего отрезка сверху, а затем берём точку справа и рисуем такой же отрезок, и после повторяем эту операцию для левой и правой части, погружаясь на всё глубже по уровню рекурсии.
Для того, чтобы нарисовать прямоугольник, нам достаточно всего трёх методов вызываемых из объекта Сairo-context — это:
- rectangle — устанавливающий параметры прямоугольника,
- fill — производящий заливку цветом,
- а так же setSourceRgb — определяющий цвет заливки.
Вообще существует большущий список методов для работы с Cairo-context, так что предлагаю ознакомиться с ним самостоятельно. В дальнейшем мы будем использовать методы из этого списка для отрисовки всё более сложных и красивых фракталов.
Ура, теперь можно сделать перерыв и выпить чашечку чая! Только что мы разобрались в том, как рисовать простейший фрактал используя PHP и Cairo!
Теперь рассмотрим пример посложнее.
Дерево Пифагора
"Пифагоровы штаны на все стороны равны. Чтобы это доказать, нужно снять и показать"
Народное творчество
Этот фрактал придумал немецкий учитель математики Альберт Босман в 1942 году и назвал его в честь древнегреческого математика Пифагора, потому как каждый уровень этого фрактала содержит фигуры, которые традиционно используются для доказательства теоремы Пифагора: три соприкасающихся квадрата, содержащих между собой прямоугольный треугольник.
Построение данного фрактала начинается с квадрата, над которым строятся ещё два квадрата, уменьшенных на величину √2/2, попарно соединённых между собой общими углами. В классическом случае, угол между двумя квадратами близлежащих уровней составляет 45°, тогда как существуют различные вариации данного фрактала:
- обнажённое дерево Пифагора — каждый квадрат заменяется отрезком
- обдуваемое ветром дерево Пифагора — углы слева и справа отличаются от 45°
- обдуваемое ветром обнажённое дерево Пифагора — сочетаются первые два пункта
Мы же рассмотрим дерево Пифагора в классическом варианте. Вот его код:
include 'drawing_window.php'; // как и ранее мы подключаем класс FractalDrawingWindow
// от которого мы унаследуем методы для работы с оконной системой
class PythagorianTree extends FractalDrawingWindow
// определим метод для отображения имени фрактала в заголовке окна
public function getName()
return "Pythagorian tree fractal";
// и метод для отрисовки самого фрактала
protected function onDraw($context)
$context->setSourceRgb(0.4, 0.9, 0.4); // определим базовый цвет отрисовки
// запустим рекурсивную функцию отрисовки нашего фрактала
$this->draw($context, $this->recursionDepth, $this->get_size()[0]/2 - 50, $this->get_size()[1], $this->get_size()[0]/2 +50, $this->get_size()[1]);
// рекурсивная функция отрисовки
public function draw($context, $depth, $x1, $y1, $x2, $y2)
// производим ограничение на глубину рекурсии
// вычисляем относительные смещения точек квадрата по осям X и Y
// изменяем координаты точек квадрата на данном уровне рекурсии
$x5 = $x4 + floatval(($dx - $dy))*0.5;
$y5 = $y4 - floatval(($dx + $dy))*0.5;
$context->MoveTo($x1, $y1); // смещаемся к координате (x1,y1) это первая точка
$context->LineTo($x2, $y2); // создаём отрезок из точки (x1,y1) к точке (x2,y2)
$context->LineTo($x3, $y3); // и т.д.
$context->LineTo($x4, $y4); // до последней вычисленной точки
$context->closePath(); // закрываем линию возвращаясь в исходную точку (x1,y1)
// устанавливаем цвет на новом уровне рекурсии
$context->setSourceRgb(1.0 - floatval($this->recursionDepth-$depth)/$this->recursionDepth, floatval($this->recursionDepth-$depth)/$this->recursionDepth, 0.0);
// делаем заливку цветом
$depth--; // декрементируем счётчик уровня рекурсии
$this->draw($context, $depth, $x4, $y4, $x5, $y5); // рисуем квадрат слева
$this->draw($context, $depth, $x5, $y5, $x3, $y3); // рисуем квадрат справа от исходного
$fractal = new PythagorianTree(); // создание объекта окна GTK с фракталом
$fractal->setRecursionDepth(10); // установ уровня рекурсии
Gtk::main(); // запуск фреймворка
Чудесно! Теперь мы видим, что можно создавать достаточно сложные фигуры сравнительно простыми методами, используя свойства рекурсии и графические примитивы библиотеки Cairo!
Здесь мы используем несколько иную технику для отрисовки прямоугольников, нежели чем в предыдущем примере. Сочетание функций moveTo , lineTo и closePath позволяет нам строить любые замкнутые многогранники. Заливка цветом при этом ничем не отличается от предыдущего случая. Мы так же указываем значения интенсивности для красного R, зелёного G и синего B каналов, передавая их в качестве параметров в функцию setSourceRgb, а затем вызываем функцию fill .
Ну и напоследок я хотел бы рассмотреть следующий фрактал.
Дракон Хартера — Хейтуэя
Итак, рассмотрим следующий код:
class DragonCurve extends FractalDrawingWindow
public function getName()
return "Dragon curve fractal";
protected function onDraw($context)
// здесь в отличие от предыдущих двух случаев мы используем итеративный метод
// создания последовательности операций отрисовки
$startAngle = -$this->recursionDepth * 3.14 / 4;
$side = 400 / pow(2, $this->recursionDepth / 2.);
$this->draw($context, $turns, $startAngle, $side, $this->get_size()[0]/2, $this->get_size()[1]/2);
// метод получения последовательности операций отрисовки дракона Хартера
public function getSequence($depth)
$seq = array(); // создаём исходный пустой массив
$copy = $seq; // создаём копию данного массива
$copy = array_reverse($copy); // инвертируем порядок элементов массива на инверсный (элементы в начале перемещаются в конец и наоборот)
// добавляем к исходному массиву код направления угла поворота линии для данного фрактала
// добавляем к исходному массиву реверсную копию инвертированных направлений углов поворота с предыдущего уровня итерации
foreach($copy as $val)
// возвращаем последовательность направлений углов поворота линий данного фрактала
// определяем функцию отрисовки для полученной последовательности направлений
public function draw($context, $turns, $startAngle, $side, $x1, $y1)
$angle = $startAngle; // устанавливаем начальный угол
$x2 = $x1 + intval(cos($angle)*$side); // производим поворот исходной точки
$y2 = $y1 + intval(sin($angle)*$side);
$context->setSourceRgb(0.4, 0.4, 0.9); // устанавливаем исходный цвет линии
// переходим к точке x1,y1
// строим отрезок к точке x2,y2
// переходим к следующей точке
foreach($turns as $turn)
$angle += $turn * 3.14 / 2; // изменяем угол поворота на 90 градусов в соответствии
// с рассчитанной заранее последовательностью
// производим поворот и отрисовку фигуры на новом уровне итерации
$x2 = $x1 + intval(cos($angle)*$side);
$y2 = $y1 + intval(sin($angle)*$side);
$fractal = new DragonCurve();
На выходе нашей программы мы увидим следующее изображение:
Закон Мёрфи призван для того, чтобы исключить всякую возможность подобного сценария. В мире программирования он выполняет очень важную роль, и его нужно всегда учитывать. И особенно его нужно учитывать, когда разрабатываемое программное обеспечение выполняет функции управления сложной техникой, от которой зависят человеческие жизни. На практике это означает более тщательный подход к разработке и тестированию программ.
В нашей статье мы рассмотрели различные виды плоских фракталов и способы их отрисовки с помощью графической библиотеки Cairo и фреймворка GTK на PHP. На этом тема фракталов и векторной графики не заканчивается. И мы более подробно раскроем её в следующей статье, которая будет посвящена фрактальной геометрии природы и грамматикам Линденмайера.
Привет, Хабр! Сегодняшний пост про фракталы попался в рамках проработки темы Python, в частности, Matplotlib. Последуем примеру автора и предупредим, что в посте много тяжелой анимации, которая может даже не работать на мобильном устройстве. Зато как красиво.
Всем приятного чтения
Фракталы прекрасны. Они выстраиваются в соответствии с очень сложным паттерном и сохраняются без искажения при любом увеличении! В этой статье мы рассмотрим, как можно с легкостью начертить фракталы нескольких видов, воспользовавшись инструментом под названием L-Systems и модулем Turtle для Python, чтобы выполнить пошаговое вычерчивание.
В этой статье мы не будем чрезмерно вдаваться в технические детали; вместо этого я ограничусь кратким введением, покажу много анимированных примеров и код, при помощи которого вы сможете сами сгенерировать такой пример. Если желаете пропустить теорию и только посмотреть анимацию, сразу переходите к примерам. Кроме того, в конце я укажу несколько ресурсов, как по написанию кода, так и по базовой математике, которые вы, возможно, захотите исследовать.
Что такое фрактал?
Это определение небезупречно, поэтому вот более точное с сайта Math World:
Как чертить фракталы при помощи Python?
Два подобных примера – квадратный остров Коха, чья структура четко вырисовывается после трех итераций, и дракон Картера-Хейтуэя, для построения полной структуры которого достаточно 8 итераций. Необходимое количество итераций сильно зависит от конкретного фрактала, с которым мы работаем.
Разумеется, существует множество библиотек на Python для построения графиков, среди которых наиболее популярна Matplotlib, но они обычно рассчитаны на нанесение статистических данных и вычерчивание хорошо известных графиков. В частности, Matplotlib содержит некоторые низкоуровневые конструкции, при помощи которых можно строить фракталы, но на этот раз мы сосредоточимся на незаслуженно малоизвестном модуле стандартной библиотеки, который называется Turtle.
Модуль Turtle
Суть заключается в том, что черепаха по умолчанию распознает 3 команды:
- Ползти вперед
- Повернуть влево на угол
- Повернуть вправо на угол
L-система – это способ представления рекурсивных структур (например, фракталов) в виде строки символов и многократной перезаписи такой строки. Опять же, дадим формальное определение:
Система Линденмайера, также известная как L-система, это механизм перезаписи строк, который может использоваться для генерации фракталов с размерностью от 1 до 2 — Math World
Поняв, что такое L-система, мы сможем создавать рекурсивные структуры, но прежде давайте разберемся, какие компоненты нам для этого понадобятся. В каждой L-системе есть:
- Алфавит: множество символов, которые будет использовать L-система.
- Аксиома: исходная строка для генерации.
- Набор инструкций создания строк: эти инструкции описывают, как каждый символ должен заменяться на следующей итерации.
Учитывая, что мы собираемся использовать Turtle для построения графиков и L-системы для представления того, что собираемся наносить на график, нам необходимо создать взаимосвязь между ними.
Поскольку в Turtle мы располагаем только теми командами, что перечислены выше, присвоим каждой из них символ; из этих символов и будет состоять алфавит.
- F: ползти вперед
- +: повернуть вправо
- -: повернуть влево
Теперь давайте перейдем к примерам!
Анимированные примеры
Следующие примеры были взяты в Интернете из нескольких общедоступных источников, и я решил портировать их на Python при помощи модуля Turtle, центрировать их, раскрасить и предоставить способ экспорта в векторный формат.
ВНИМАНИЕ: предлагаемые анимации достаточно велики, рекомендуется смотреть их лишь с хорошим интернетом. Код Repl может не работать, так как потребляет ваши ресурсы, и с отображением фракталов на мобильных устройствах возможны проблемы.
Внимание: Skulpt использует для рендеринга и создания анимации ВАШ БРАУЗЕР, так что при подвисании, лагах или любом странном поведении обычно достаточно просто заново воспроизвести анимацию или перезагрузить страницу. На мобильном устройстве может не работать.
Примеры даны в порядке усложнения (на мой субъективный взгляд), так что самое интересное – в конце.
Войти
Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal
Программы генераторы фракталов
Основные генераторы фракталов
В этом уроке Фотошопа мы рассмотрим процесс создания фрактальных изображений.
Категория: Эффекты
Сложность: Средняя
Дата: 05.09.2013
Обновлено: 18.06.2015
Финальный результат
Спорю, каждый из вас видел фрактальные изображения. Кто-то увидел их на обложке журнала, а кто-то в галерее, а кто-то просто разглядел узор на какой-нибудь плитке. И если вы вглядывались в картинку, то вы видели повторяющиеся фигуры, соединяющиеся в узор. В этом уроке Фотошопа мы научимся сами создавать подобные картинки.
Шаг 1
Шаг 2
Шаг 3
Шаг 4
Теперь соедините все четыре фигуры.
Прим. Переводчика: К сожалению, автор не указывает, как он это сделал и лично у меня после обычного соединения получается не пойми что… Поэтому мы не просто нажимаем Ctrl+E, а убираем ненужные слои и оставляем только кружки, затем Layer - Merge Visible (Слои - Объединить видимые / Shift+Ctrl+E).
Шаг 5
Ну а сейчас самая веселая часть! Ну сперва мы, как вы уже наверно поняли дублируем слой и нажимаем Ctrl+T. Уменьшаем нашу копию, немного нагибаем ее и самое ВАЖНОЕ – убираем transform center (+ в середине трансформации) в сторону.
Шаг 6
Шаг 7
Подвинем наш фрактал немного влево, как показано на картинке ниже. Затем продублируйте два раза вашу папку с фракталом. Для обеих выберете Merge Group (Объединить группу). Одна будет у нас, как копия оригинала, а вторая другим фракталом.
Шаг 8
Поверните вторую копию фрактала, как показано на рисунке ниже.
Шаг 9
Так, а теперь мы повторим шаг 6, тобишь нажнем полюбившиеся нам клавиши Ctrl+Shift+Alt+T и вуаля! Мы получили третий фрактал, ничего не вращая и не дублируя, умный фотошоп все сделал за нас. Теперь, когда у нас есть все три фрактала поместите их в одну папку и назовите ее fractal 2. Продублируйте папку, кликните правой кнопкой мыши по ней и выберете Merge Group (Объединить группу).
Шаг 10
Продублируйте слой и нажмите Ctrl+T и с помощью зажатого Shift+Alt поверните и чуть-чуть уменьшите ее.
Шаг 11
Шаг 12
И снова копируем, трансформируем и меняем цвет.
Шаг 13
Повторите заветную комбинацию этого урока (я о Ctrl+Shift+Alt+T), но на этот раз, сколько вашей душе угодно. Главное не забудьте менять цвет ваших фракталов. Когда закончите, поместите все слои в папку и назовите ее Fractal 3. Ну а теперь, как и в предыдущих шагах продублируйте папку и соедините все слои в ней, с помощью функции Merge Group (Объединить группу). Назовите ее fractal 3.
Шаг 14
Добавьте теней фракталу.
Шаг 15
Шаг 16
Free Transform (Свободная трансформация) снова (Ctrl+Shift+Alt+T) сколько вашей душе угодно.
Заключение - Как вы видите в конце мы создали, что-то абстрактное с помощью фрактальных форм. Вроде бы неплохо получилось. Теперь осталось только подключить ваше воображение.
Финальный результат
Чудо-ролик 03.02.2015 --> Смотрели: 70 (4)
-Поиск по дневнику
-Статистика
Для вашего удобства, дорогие друзья, решила собрать уроки по созданию фракталов в одну кучу. Это список будет пополняться по мере написания новых уроков.
Уроки по созданию фракталов
в программе Fractal Explorer.
Уроки по созданию фракталов
в программе Ultra Fractal
Уроки по созданию фракталов
в программе Apophysis
Уроки по созданию фракталов
Уроки по созданию фракталов
в программе Mandelbulb3D
Уроки по созданию фракталов
Рубрики: | Создание_фракталов_(уроки,_руководства) |
Процитировано 58 раз
Понравилось: 30 пользователям
Да, не за что!
Не за что!
Спасибо,за интересный пост.
Большое спасибо!
K_E_T, Здравствуйте,скажите пожалуйста.вы не могли бы дать ссылку на скачивание какой нибудь программы ,которая полегче,потому что я вообще не знакома с фракталами,хочется попробовать,не знаю,смогу ли?
Ой, он у меня слетел, вообще часть дневника потеряла, там были некоторые уроки. Попробую его восстановить, скрины у меня остались.
Да он уже написан. Его, просто, надо выставить. Я как Плюшкин, все уроки сохраняю в текстовом варианте.
У меня причятельница увлечена составлением фракталов.Очень красивые.Найду время,чтобы попробовать.Спасибо за такую огромную работу!
Читайте также: