Фрактал Курликю

В этой статье я опять покажу дорогу в странное, показав как используя 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):

Вот собственно и все.

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