L-системы

Из интересной и очень познавательной книги «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-система так:
ls1_0_oСоты:

l:=30
a:=60
gener:=15
axiom:="X"
rewrite["X"]:="F[-X+X]"

А смотрится это так:
ls2_0_oЗвезда Коха:

l:=10
a:=60
gener:=5
axiom:="F"
rewrite["F"]:="F-F++F-F"

И вновь картинка с L-системой:
ls3_0_oКривая Хартера-Хейтвея:

l:=2
a:=90
gener:=15
axiom:="FX"
rewrite["X"]:="X+YF"
rewrite["Y"]:="FX-Y"

И получается замечательная кривая «дракона»:
ls4_0_oНапоследок, математическая красота растений:

l:=5
a:=25.7
gener:=5
axiom:="F"
rewrite["F"]:="F[+F]F[-F]F"

ls5_0_o

l:=10 
a:=20 
gener:=5
axiom:="F" 
rewrite["F"]:="F[+F]F[-F][F]"

ls6_0_o

l:=10
a:=22.5
gener:=5
axiom:="F"
rewrite["F"]:="FF-[-F+F+F]+[+F-F-F]"

ls7_0_o

l:=4
a:=20
gener:=6
axiom:="X"
rewrite["X"]:="F[+X]F[-X]+X"
rewrite["F"]:="FF"

ls8_0_o

l:=4
a:=25.7
gener:=6
axiom:="X"
rewrite["X"]:="F[+X][-X]FX"
rewrite["F"]:="FF"

ls9_0_o

l:=4
a:=25.7
gener:=6
axiom:="X"
rewrite["X"]:="F-X]+X]+F[+FX]-X"
rewrite["F"]:="FF"

ls10_0_oДля гурманов выкладываю параметры и аксиомы 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 поколений

Добавить комментарий