
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




EnableExplicit
DisableDebugger
 
DataSection
  R84:  : Data.d 0.85,0.04,-0.04,0.85,1.6
  R91:  : Data.d 0.2,-0.26,0.23,0.22,1.6
  R98:  : Data.d -0.15,0.28,0.26,0.24,0.44
  R100: : Data.d 0.0,0.0,0.0,0.16,0.0
EndDataSection
 
Procedure Barnsley(height.i) 
  Define x.d, y.d, xn.d, yn.d, v1.d, v2.d, v3.d, v4.d, v5.d,
         f.d=height/10.6,
         offset.i=Int(height/4-height/40),
         n.i, r.i  
  For n=1 To height*50
    r=Random(99,0)
    Select r
      Case 0 To 84  : Restore R84
      Case 85 To 91 : Restore R91
      Case 92 To 98 : Restore R98
      Default       : Restore R100
    EndSelect
    Read.d v1 : Read.d v2 : Read.d v3 : Read.d v4 : Read.d v5
    xn=v1*x+v2*y : yn=v3*x+v4*y+v5    
    x=xn : y=yn
    Plot(offset+x*f,height-y*f,RGB(0,255,0))
  Next
EndProcedure
 
Define w1.i=400,
       h1.i=800
 
If OpenWindow(0,#PB_Ignore,#PB_Ignore,w1,h1,"Barnsley fern")
  If CreateImage(0,w1,h1,24,0) And StartDrawing(ImageOutput(0))        
    Barnsley(h1)
    StopDrawing()
  EndIf
  ImageGadget(0,0,0,0,0,ImageID(0))  
  Repeat : Until WaitWindowEvent(50)=#PB_Event_CloseWindow
EndIf
End