Как сделать фрактал онлайн

Обновлено: 04.07.2024

В этой статье мы узнаем что такое фракталы и как рисовать их на 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

Программы генераторы фракталов

Основные генераторы фракталов



Five o’clock



В этом уроке Фотошопа мы рассмотрим процесс создания фрактальных изображений.

Категория: Эффекты

Сложность: Средняя

Дата: 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, Здравствуйте,скажите пожалуйста.вы не могли бы дать ссылку на скачивание какой нибудь программы ,которая полегче,потому что я вообще не знакома с фракталами,хочется попробовать,не знаю,смогу ли?

Ой, он у меня слетел, вообще часть дневника потеряла, там были некоторые уроки. Попробую его восстановить, скрины у меня остались.

Да он уже написан. Его, просто, надо выставить. Я как Плюшкин, все уроки сохраняю в текстовом варианте.

У меня причятельница увлечена составлением фракталов.Очень красивые.Найду время,чтобы попробовать.Спасибо за такую огромную работу!

Читайте также: