В этой статье я опять покажу дорогу в странное, показав как используя dlib построить довольно необычный и интересный фрактал, мало известный в кругах любителей фракталов, а потому очень и очень любопытный…
Для начала эксперимента создаем пустой проект dub и добавляем в него зависимость dlib (надеюсь, как это сделать напоминать не надо) и добавляем туда теперь уже стандартную процедуру генерации белового фона:
auto simg = image(1000, 1000); for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; j++) { simg[i, j] = Color4f(1.0f, 1.0f, 1.0f); } }
После чего, введем вспомогательную процедуру прорисовки линии по алгоритму DDA (уже упоминали в блоге):
// рисование линии методом DDA void drawLine(ref SuperImage simg, Color4f color, int x1, int y1, int x2, int y2, int width = 1) { import std.algorithm : max; import std.math : abs; int deltaX = abs(x1 - x2); int deltaY = abs(y1 - y2); int length = max(deltaX, deltaY); if (length == 0) { simg.fillRectangle(color, x1, y1, width, width); } float dx = cast(float) (x2 - x1) / cast(float) length; float dy = cast(float) (y2 - y1) / cast(float) length; float x = x1; float y = y1; length++; while(length--) { x += dx; y += dy; simg.fillRectangle(color, cast(int) x, cast(int) y, width, width); } }
И вот теперь мы можем перейти к самому сокровенному - созданию изображения фрактала Курликю.
Курликю, как мне казалось, это фамилия ученого, который занимался математикой таких геометрических образов, но внезапно выяснилось, что curlicue - это испанское выражение, переводящееся как "причудливый узор" и что характерно, такой фрактал именно так и выглядит.
Фрактал Курликю имеет несколько параметров: r - длина кривой Корню (о том, что это такое и как выглядит здесь), t - показатель степени, в которую возводится переменная в ходе расчета фрактала, s - параметр, более точно определяющий угол поворота кривой Корню и параметр step - параметр, показывающий приращение в изменении степени (спасибо ребятам с этого сайта за хорошо описанную теорию и грамотный код, поясняющий работу фрактала).
В итоге, мы получаем такой код, который включает в себя переход от полярных координат к декартовым:
// фрактал Курликю void CurlicueFractal(ref SuperImage simg, float r, float t, float s, float step) { import std.math : abs, cos, sin, PI; int OX = 300; int OY = 300; int Xstart = 0; int Ystart = 100; for (int v = -10_000; v <= 10_000; v += step) { float w = s * (v ^^ t); int X = cast(int) (Xstart + r * cos(w)); int Y = cast(int) (Ystart - r * sin(w)); auto red = cast(float) (abs(v / 4 + 1024) % 255); auto green = cast(float) (abs(255 - v / 3) % 255); auto blue = cast(float) (abs(128 - v) % 255); Color4f color = Color4f(red / 255.0, green / 255.0, blue / 255.0); simg.drawLine(color, OX + Xstart, OY + Ystart, OX + X, OY + Y, 2); Xstart = X; Ystart = Y; } }
И результат для запуска функции CurlicueFractal(simg, 10, 2, 10, 1):
Вот собственно и все.
Один комментарий к “Фрактал Курликю”