
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




 
link graphics
 
global x, y
 
procedure main()
    &window := open("FERN", "g", "size=400,400", "bg=black")
 
    x := y := 0
 
    repeat {
	draw()
	delay(30)
	if *Pending() > 0 then {
	    case Event() of {
	        "q"|"\e": return
            }
	}
    }
end
 
procedure next_point()
    local nx, ny, r
 
    nx := 0.0
    ny := 0.0
 
    r := ?100
 
    if r < 1 then {
	nx := 0.0
	ny := 0.16 * y
    } else if r < 86 then {
	nx := 0.85 * x + 0.04 * y
	ny := -0.04 * x + 0.85 * y + 1.6
    } else if r < 93 then {
	nx := 0.2 * x - 0.26 * y
	ny := 0.23 * x + 0.22 * y + 1.6
    } else {
	nx := -0.15 * x + 0.28 * y
	ny := 0.26 * x + 0.24 * y + 0.44
    }
 
    x := nx
    y := ny
end
 
procedure map(v:real, a, b, c, d)
    return (v - a) / (b - a) * (d - c) + c;
end
 
procedure draw_point()
    local px, py
 
    px := map(x, -2.1820, 2.6558, 0.0, 400.0)
    py := map(y, 0.0, 9.9983, 400.0, 0.0)
 
    Fg("green")
    DrawPoint(px, py)
end
 
procedure draw()
    every i := 0 to 10000 do {
	draw_point()
	next_point()
    }
end
 