Lindenmayersystem mit LParser umsetzen:
Auf der LParser-Seite von L. Lapre (siehe Linkseite) wird auf eine englischsprachige Seite mit einfachen Beispielen und Erklärungen verwiesen.
Aus der Datei LPARSER.TXT die Befehle im Original:
---------------------------------------------------------------------------
Turtle Orientation commands
---------------------------------------------------------------------------
+ turn left around up vector
+(x) turn x left around up vector
- turn right around up vector
-(x) turn x right around up vector
& pitch down around left vector
&(x) pitch x down around left vector
^ pitch up around left vector
^(x) pitch x up around left vector
< roll left (counter clockwise) around forward vector
<(x) roll x left around forward vector
> roll right (clockwise) around forward vector
>(x) roll x right around forward vector
---------------------------------------------------------------------------
Special Orientation commands
---------------------------------------------------------------------------
| turn 180 deg around up vector
% roll 180 deg around forward vector
$ roll until horizontal
~ turn/pitch/roll in a random direction
~(x) " in a random direction with a maximum of x degrees
t correction for gravity with 0.2
t(x) correction for gravity with x
---------------------------------------------------------------------------
Movement commands when {} active
---------------------------------------------------------------------------
F move forward and draw full length record vertex
F(x) move x forward and draw record vertex
Z move forward and draw half length record vertex
Z(x) move x forward and draw record vertex
f move forward with full length record vertex
f(x) move x forward record vertex
z move forward with half length record vertex
z(x) move x forward record vertex
g move forward with full length don't record vertex
g(x) move x forward don't record vertex
. don't move record vertex
---------------------------------------------------------------------------
Structure commands
---------------------------------------------------------------------------
[ push current state
] pop current state
{ start polygon shape
} end polygon shape
---------------------------------------------------------------------------
Inc/Dec commands
---------------------------------------------------------------------------
" increment length with 1.1
' decrement length with 0.9
"(x) multiply length with x also '(x)
; increment angle with 1.1
: decrement angle with 0.9
:(x) multiply angle with x also ;(x)
? increment thickness with 1.4
! decrement thickness with 0.7
?(x) multiply thickness with x also !(x)
---------------------------------------------------------------------------
Additional commands
---------------------------------------------------------------------------
c increment color index
c(x) set color index to x
@ end of object
---------------------------------------------------------------------------
Leider entspricht das von LParser benutzte rechtshändige Koordinatensystem nicht dem ... Koordinatensystem von PoVRay. Die Voreinstellung ist: Die z-Achse gilt als vorwärts-Achse beim Programmstart und die y-Achse gilt als links-Richtung.
PoVRay hat ein linkshändiges Koordinatensystem: (Linke Hand: Wenn man Daumen, Zeigefinger und Mittelfinger zueinander senkrecht hält, dann gilt: Hält man den Zeigefinger in x-Achsenrichtung und den Mittelfinger in y-Achsenrichtung, dann zeigt der Daumen in die Richtung der positiven z-Achse, vgl. Abbildung)
Bei PoVRay entspricht also die Monitor-Ebene der xy-Ebene und die z-Achse zeigt in den Monitor hinein.
Bei LParser entspricht die yz-Ebene mit nach links weisender y-Achse der Monitor-Ebene, die x-Achse zeigt in den Monitor hinein.

Tipp für die Benutzung von LParser: Mit einem Dollarzeichen vor Beginn eigener Zeichenketten in der Ersetzungsregel wird die Bewegungsrichtung der "Schildkröte (turtle)" waagrecht gestellt und der aktuelle "Aufwärtsvektor" liegt in Richtung der positiven z-Achse.
Mit der mitgelieferten Datei "axis.ls" werden die 3 Achsen abgebildet.
Ein (minimales) LParser-Skript ist folgendermaßen ausgebaut:
1. Anzahl der Schleifendurchgänge
2. Angabe des Drehwinkels
3. Angabe der Dicke des Grundelements in % seiner Länge
4. die Zeichenanweisung (das "Axiom")
5. nötige Definition des verwendeten Elements
6. das Dateiende-Zeichen
Einfache Beispiele:
Beispiel 1: Die 4 Richtungen +, -, & und ^ :
+ in den Bildschirm
- aus dem Bildschirm
& Bildschirm links
^ Bildschirm rechts

Das folgende Skript ist rekursiv: Die Zeichenanweisung ruft sich selbst wieder auf.
14 #Anzahl der Schleifendurchgänge 25 #Drehwinkel 50 #Radius des Zeichenelements [A]c[B]c[C]c[D] #Axiom A=+FA #drehe nach links um die x-Achse um 25°, zeichne eine Linie und wh. B=-FB #drehe nach rechts um die x-Achse um 25°, zeichne eine Linie und wh. C=^FB #drehe nach rechts um die y-Achse um 25°, zeichne eine Linie und wh. D=&FD #drehe nach links um die y-Achse um 25°, zeichne eine Linie und wh. @
Vor dem Zeichnen von A wird die aktuelle Position gespeichert (Ablage auf dem Stack), danach wieder hergestellt (oberste Adresse vom Stack).

(Das Koordinatensystem wurde nachträglich eingefügt. Kameraposition und Lichtquellen wurden ebenfalls im PoV-Skript geändert)
Datei lsys_02.ls
Datei lsys_02.pov
Datei lsys_02.inc
verändert man das LS-Skript nur wenig (Hinzufügen von Richtungsänderungen und " ' " für eine Verkürzung des Zeichenelements auf 90%), dann entsteht ein ganz anderes Bild, zwar hässlich aber informativ:
Das Skript:
14 #Anzahl der Schleifendurchgänge 75 #Drehwinkel 30 #Radius des Zeichenelements [A]c[B]c[C]c[D] #Axiom (mit Farbindexerhöhung und Merken/Wiederherstellen der Position) A=+^'FA #drehe nach links um die x-Achse um 25°, zeichne eine Linie und wh. B=-&'FB #drehe nach rechts um die x-Achse um 25°, zeichne eine Linie und wh. C=^'FC #drehe nach rechts um die y-Achse um 25°, zeichne eine Linie und wh. D=&'FD #drehe nach links um die y-Achse um 25°, zeichne eine Linie und wh. @
Beispiel 2: Ein paar neue Anweisungen dazu:
6 # Anzahl der Iterationsschritte
12 # Winkel
100 # Durchmesser des Zeichenelements
Ef<Ef>E # AXIOM
E=[A][B][C][D]<[A]<[B]<[C]<[D] # als Alternative: >[A]>[B]>[C]>[D]
# < und >: Drehungen im und geg. d. Uhrz.sinn um die x-Achse
# Es folgen die Ersetzungsregeln
A=zc"(0.98);(1.05)!(.98)+ZA # c : Änderung d. Farbindex, z: Vorwärtsbew. mit halber Länge
# " : Streckfaktor für die Länge 1.1. "(0.98) : jetzt 0.98
# ! : Streckfaktor für die Dicke ist 0.7
B=gc"(0.98);(0.95)!(.98)-ZB # g : wie f, Vorwärtsbew. m. voller Länge ohne zu zeichnen
C=zc"(0.98);(0.85)!(.98)^ZC # + - ^ & : die vier Richtungen
# ; : Winkelfaktor ist 1.1 od. was in der ff. Klammer steht
D=gc"(0.98);(1.15)!(.98)&ZD
@
Beispiel 3: Wieder ein rekursives Beispiel, 2-dimensional:
12 # Rekursionstiefe 15 # Winkel 100 # Durchmesser des Zeichenelements AFB # AXIOM A=AF B=[+AFB][-AFB] @
Diesmal haben wir einen 2-dimensionalen Baum (außer + und - tauchen die Richtungs- und Drehbefehle im Skript nicht auf), allerdings etwas zu regelmäßig, um als Baum durchgehen zu können.
Beispiel 4: Bringen wir ein paar Änderungen in das Skript:
12 # Rekursionstiefe
15 # Winkel
100 # Durchmesser des Zeichenelements
AFB # AXIOM
A=AF
B=[+(27)AcFB][-(13)Acc!(0.8)'(0.65)FB]
#Dicke und Länge des Zeichenelements werden lt. Klammer
#geändert,
# die Drehwinkel ebenso, gleich noch Farbvariationen hinzu
@
Diesmal haben wir einen unsymmetrischen Baum, immerhin, aber dem Zufall einen Einfluß geben, könnte auch nicht schaden.
12 # Rekursionstiefe 15 # Winkel 100 # Durchmesser des Zeichenelements AFB # AXIOM A=AF B=[~(90)AcFB][~(90)Acc!(0.8)'(0.65)FB] @
Mit ~(x) kann man eine Drehung in zufälliger Richtung erzeugen - maximal um x°.
Etwas mehr Variation wurde erreicht, aber Wind und Wetter haben diesen Baum doch arg gebeutelt. Der Maximalwinkel von 90° kann ja noch verkleinert werden.
Beispiel 5:
Eine sehr einfache Initialisierung hat auch die Kochkurve. Hier produziert LParser schon nach wenigen Iterationsschritten riesengroße include-Dateien, entsprechend lange dauert dann die Umsetzung mit PoVRay
Für solche Beispiele ist die Umsetzung mit einem Fraktalprogramm geeigneter.
4 # Rekursionstiefe 90 # Winkel 10 # Durchmesser des Zeichenelements F # AXIOM F=F+F-F-F+F @
Beispiel 6:
Als letztes Beispiel noch ein Gras (nach einer Idee aus einer Veröffentlichung von R.Deißler über fraktale Geometrie im SS 2000):
2 #Rekursionstiefe 15 #Winkel 10 #Dicke wH[wÄ]-H[wÄ]+H[wÄ]-H Ä #Axiom: Ä steht für Ähre H=HFFF #H Längenwachstumszone, H für Hauptstiel, weniger F: buschiger w=Fw #Längenwachstumszonen für Ährenstiel und Seitenästchen 2=F2 #s.o. Ä=F[-F1]F[+F1]FFÄ #Ä für den Hauptstiel 1=F[+2]F[-2]1 #1 und 2 für Seitenästchen 1. und 2. Ordnung 2=F2 @
In der include-Datei für Povray wurden Zeichenlänge und -farbe geändert.
| © 2009 Asti | Links für Unterricht | PoVRay-Site |