
A Barnsley fern is a fractal named after British mathematician Michael Barnsley and can be created using an iterated function system (IFS).



Task

Create this fractal fern, using the following transformations:

 ƒ1   (chosen 1% of the time)
        xn + 1 = 0
        yn + 1 = 0.16 yn

 ƒ2   (chosen 85% of the time)
        xn + 1 = 0.85 xn + 0.04 yn
        yn + 1 = −0.04 xn + 0.85 yn + 1.6

 ƒ3   (chosen 7% of the time)
        xn + 1 = 0.2 xn − 0.26 yn
        yn + 1 = 0.23 xn + 0.22 yn + 1.6

 ƒ4   (chosen 7% of the time)
        xn + 1 = −0.15 xn + 0.28 yn
        yn + 1 = 0.26 xn + 0.24 yn + 0.44.

Starting position: x = 0, y = 0




#!/usr/bin/env dub
/+ dub.sdl:
	dependency "dlib" version="~>0.21.0"
+/
import std.random;
 
import dlib.image;
 
void main()
{
	enum WIDTH = 640;
	enum HEIGHT = 640;
	enum ITERATIONS = 2E6;
 
	float x = 0.0f;
	float y = 0.0f;
 
	auto rng = Random(unpredictableSeed);
	auto color = Color4f(0.0f, 1.0f, 0.0f);
	auto img = image(WIDTH, HEIGHT);
 
	foreach (_; 0..ITERATIONS)
	{
		auto r = uniform(0, 101, rng);
 
		if (r <= 1)
		{
			x = 0.0;
			y = 0.16 * y;
		}
		else
		{
			if (r <= 8)
			{
				x = 0.20 * x - 0.26 * y;  
				y = 0.23 * x + 0.22 * y + 1.60;
			}
			else
			{
				if (r <= 15)
				{
					x = -0.15 * x + 0.28 * y; 
					y = 0.26 * x + 0.24 * y + 0.44;
				}
				else
				{
					x = 0.85 * x + 0.04 * y;
					y = -0.04 * x + 0.85 * y + 1.6;
				}
			}
		}
		auto X = cast(int) (WIDTH / 2.0 + x * 60);
		auto Y =  HEIGHT - cast(int)(y * 60);
		img[X, Y] = color;
	}
	img.saveImage(`barnsley_dlib.png`);
}