Draws fractals using L-Systems.
'# '# L-System Fractal Viewer '# By Rich Dodson a.k.a. Sushimasta '# 2006 '# SuperStrict SeedRnd MilliSecs() Type TRule Global _rules:TList = CreateList() Field _before:String Field _after:String Method Construct:TRule(before:String, after:String) _rules.AddLast(Self) _before = before _after = after Return Self EndMethod Method Destruct() _rules.Remove(Self) EndMethod Function GetRules:TList() Return _rules EndFunction Method GetBefore:String() Return _before EndMethod Method GetAfter:String() Return _after EndMethod EndType Function Rule(before:String, after:String) New TRule.Construct(before, after) EndFunction '# '# ------------------------- '# L-System Fractal Design '# Move the fractal around the screen using the mouse '# Click the left mouse button to draw the next level of the fractal '# Don't increase the level too high as the time it takes to compute increases exponentially '# '# Length of each line Const radius:Float = 10.0 '# Angle of each turn Const angle:Float = 60.0 '# Initial axiom for fractal Local line:String = "F" '# Rules for expanding a fractal Rule("F", "F+F--F+F") '# '# Rules are in the form of before -> after where each occurance of before is replaced with after '# In the above example, each occurance of F is is replaced by F+F--F+F '# Strings are executed as commands to a Turtle drawer '# '# Characters: '# F - Draw a line with length radius '# + - Turn left by angle '# - - Turn right by angle '# [ - Push current state on to stack '# ] - Pop current state off of stack '# '# '# For example: '# F '# F+F--F+F '# F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F '# etc, etc. '# ------------------------- '# Graphics(800, 600, 32, 60) HideMouse() Local timer:TTimer = CreateTimer(60) Local advance:Int = 0 Repeat Select WaitEvent() Case EVENT_KEYDOWN Select EventData() Case KEY_ESCAPE Exit EndSelect Case EVENT_MOUSEDOWN Select EventData() Case MOUSE_LEFT advance :+ 1 EndSelect Case EVENT_TIMERTICK If EventSource() = timer Cls RunTurtle(line, MouseX(), MouseY(), 0.0) If KeyDown(KEY_TAB) DrawText(line, 0, 0) DrawText(line.length, 0, 20) EndIf Flip If advance Local nline:String = "" Local p:Int = 0 While p < line.length Local c:String = line[p..p + 1] Local matched:Int = False For Local rule:TRule = EachIn TRule.GetRules() Local l:Int = rule.GetBefore().length If line[p..p + l] = rule.GetBefore() nline :+ rule.GetAfter() matched = True p :+ l Exit EndIf Next If Not matched nline :+ c p :+ 1 EndIf Wend line = nline advance :- 1 EndIf EndIf EndSelect Forever For Local rule:TRule = EachIn TRule.GetRules() rule.Destruct() Next Function RunTurtle(line:String, x:Float, y:Float, a:Float) Global stack:Float[] = New Float[256] Global index:Float = 0 For Local p:Int = 0 Until line.length Local c:String = line[p..p + 1] If "A" <= c And c <= "Z" Local nx:Float = x + radius * Cos(a) Local ny:Float = y + radius * Sin(a) DrawLine(x, y, nx, ny) x = nx y = ny Else Select c Case "+" a :- angle Case "-" a :+ angle Case "[" stack[index] = x stack[index + 1] = y stack[index + 2] = a index :+ 3 Case "]" index :- 3 x = stack[index] y = stack[index + 1] a = stack[index + 2] EndSelect EndIf Next EndFunction