Из интересной и очень познавательной книги «Graphic Programming in Icon» мне очень понравилась реализация L-систем на основе одной из библиотек IPL — turtle («черепашья графика», как в Лого), которая выглядит примерно вот так (правда, пришлось модифицировать программу, иначе она не работоспособна):
link graphics,turtle procedure main() local W,l,a,rewrite,current_string,new_string,c,t,gener W:=WOpen("label=l-system","size=500,500") l:=2 a:=90 gener:=5 Fg("dark green") axiom:="F" rewrite:=table() rewrite["F"]:="F-F++F-F" current_string:=axiom every 1 to gener do { new_string:="" every c:=!current_string do new_string||:=(rewrite[c] | c) current_string:=new_string } TGoto(250,500) every c:=!current_string do { case c of { "F" : TDraw(l) "f" : TSkip(l) "+" : TRight(a) "-" : TLeft(a) "[" : TSave() "]" : TRestore() } } WDone() end
Процедура не универсальна, и если нужно произвести эксперимент, то нужно вручную изменять переменные: l — длина линии, a — угол поворота «черепахи», gener — количество итераций (количество поколений L-системы) в ходе переписывания, axiom — аксиома (начальное правило для L-системы), rewrite[«переменная для переписывания»]:=»строка замены» (правило переписывания строки.).
Естественно, существует много различных аксиом и правил их переписывания — но я покажу некоторые из них.
Квадраты:
l:=5 a:=90 gener:=4 axiom:="F+F+F+F" rewrite["F"]:="F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF" rewrite["f"]:="ffffff"
Выглядит эта L-система так:
Соты:
l:=30 a:=60 gener:=15 axiom:="X" rewrite["X"]:="F[-X+X]"
А смотрится это так:
Звезда Коха:
l:=10 a:=60 gener:=5 axiom:="F" rewrite["F"]:="F-F++F-F"
И вновь картинка с L-системой:
Кривая Хартера-Хейтвея:
l:=2 a:=90 gener:=15 axiom:="FX" rewrite["X"]:="X+YF" rewrite["Y"]:="FX-Y"
И получается замечательная кривая «дракона»:
Напоследок, математическая красота растений:
l:=5 a:=25.7 gener:=5 axiom:="F" rewrite["F"]:="F[+F]F[-F]F"
l:=10 a:=20 gener:=5 axiom:="F" rewrite["F"]:="F[+F]F[-F][F]"
l:=10 a:=22.5 gener:=5 axiom:="F" rewrite["F"]:="FF-[-F+F+F]+[+F-F-F]"
l:=4 a:=20 gener:=6 axiom:="X" rewrite["X"]:="F[+X]F[-X]+X" rewrite["F"]:="FF"
l:=4 a:=25.7 gener:=6 axiom:="X" rewrite["X"]:="F[+X][-X]FX" rewrite["F"]:="FF"
l:=4 a:=25.7 gener:=6 axiom:="X" rewrite["X"]:="F-X]+X]+F[+FX]-X" rewrite["F"]:="FF"
Для гурманов выкладываю параметры и аксиомы L-систем:
L-системы: Квадраты: l:=5 a:=90 axiom:="F+F+F+F" rewrite["F"]:="F+f-FF+F+FF+Ff+FF-f+FF-F-FF-Ff-FFF" rewrite["f"]:="ffffff" 4 поколения Соты: l:=30 a:=60 axiom:="X" rewrite["X"]:="F[[-X+X]" 15 поколений Звезда Коха: l:=10 a:=60 axiom:="F" rewrite["F"]:="F-F++F-F" 5 поколений Кривая Хартера-Хейтвея: l:=2 a:=90 axiom:="FX" rewrite["X"]:="X+YF" rewrite["Y"]:="FX-Y" 15 поколений Растения: l:=5 a:=25.7 axiom:="F" rewrite["F"]:="F[+F]F[-F]F" 5 поколений l:=10 a:=20 axiom:="F" rewrite["F"]:="F[+F]F[-F][F]" 5 поколений l:=10 a:=22.5 axiom:="F" rewrite["F"]:="FF-[-F+F+F]+[+F-F-F]" 5 поколений l:=4 a:=20 axiom:="X" rewrite["X"]:="F[+X]F[-X]+X" rewrite["F"]:="FF" 6 поколений l:=4 a:=25.7 axiom:="X" rewrite["X"]:="F[+X][-X]FX" rewrite["F"]:="FF" 6 поколений l:=4 a:=25.7 axiom:="X" rewrite["X"]:="F-[[X]+X]+F[+FX]-X" rewrite["F"]:="FF" 6 поколений