95 lines
4.7 KiB
Markdown
95 lines
4.7 KiB
Markdown
# Visualisierung von Lindermayer-Systemen
|
|
|
|
von Marcel Zinkel, 19.01.2022
|
|
|
|
## Theorie
|
|
|
|
### formale Definition
|
|
|
|
Ein Lindenmayer-System (auch L-System) ist ein Quadrupel G=(V,S,$\omega$,P).
|
|
|
|
- V ist die Menge der Variablen.
|
|
- S ist die Menge der Konstanten. Die Mengen V und S bilden das Alphabet.
|
|
- $\omega$ ist ein Wort aus Zeichen des Alphabets, das man auch Startwort nennt.
|
|
- P ist eine Menge von Paaren von Variablen und Wörtern, die die Ersetzungsregeln
|
|
definieren.
|
|
|
|
### kontextfreie L-Systeme
|
|
|
|
Beim Erzeugen eines L-Systems wird eine Tiefe n festgelegt, mit der die Ersetzungsschritte
|
|
wiederholt werden. Für jedem Ersetzungsschritt wird jedes Zeichen des aktuellen Wortes
|
|
$\omega$ durchgegangen und jeweils die Variablen durch das in den Ersetzungsregeln
|
|
festgelegt gelegte Wort ersetzt. Die Konstanten werden nicht ersetzt.
|
|
|
|
### Visualisierung
|
|
|
|
Eine übliche Visualisierung besteht darin, dass eine Figur z. B. eine Schildkröte
|
|
in Python über den Bildschirm bewegt wird. Folgende Zeichen haben dabei eine besondere
|
|
Bedeutung:
|
|
|
|
- F: Bewegung nach vorne um eine bestimmte Länge und Zeichnen einer Linie
|
|
- +: Drehung im mathematisch positiven Sinne um den Winkel $\alpha$
|
|
- -: Drehung im mathematisch negativen Sinne um den Winkel $\alpha$
|
|
- [: speichert die Position und Rotation auf einem Stack
|
|
- ]: stellt die oberste Position und Rotation des Stacks wieder her
|
|
|
|
## Implementierung
|
|
|
|
Das Programm wird in Python implementiert, wofür mindestens die Version 3.10 benötigt
|
|
wird, weil die match-case-Anweisung verwendet wird, die in dieser Version eingeführt
|
|
wurde. Als Abhängigkeit wird das pip-Paket pillow benötigt. Dies kann mit
|
|
`pip install .` installiert werden. Optional für das Exportieren als Bild wird
|
|
[Ghostscript](https://www.ghostscript.com/) benötigt.
|
|
|
|
Alle Schildkröten werden mit der `newTurtle` Funktion in der `drawer.py`
|
|
erstellt. Diese sorgt dafür, dass alles so schnell wie möglich gezeichnet wird
|
|
und die Schildkröte nicht zu sehen ist.
|
|
|
|
Die Klasse `Drawer` in der `drawer.py` ist am wichtigsten, da diese die
|
|
L-Systeme zeichnet. Die `draw` Methode dieser Klasse geht Zeichen für Zeichen
|
|
des Wortes, mit der sie aufgerufen wurde, durch. Bei + oder - wird die
|
|
Schildkröte nach links bzw. rechts um einen zuvor festgelegten Winkel gedreht.
|
|
Bei F wird sie nach vorne bewegt. In der Liste `turtleStates` wird der Zustand
|
|
der Schildkröte, also die Position und Rotation, gespeichert. Bei [ wird wird
|
|
der Zustand am Ende der Liste gespeichert und bei ] der letzte Zustand der Liste
|
|
wiederhergestellt und anschließend gelöscht. Außerdem wird für Zeichen, für die
|
|
es eine Ersetzungsregel gibt, die `draw` Methode rekursiv mit dem der
|
|
Ersetzungsregel entsprechenden Wort aufgerufen.
|
|
|
|
Die Klasse `DrawerSimulation` erbt von `Drawer` und simuliert ein L-System und
|
|
ermittelt Bereich, indem es gezeichnet werden würde. So kann die `draw` Funktion
|
|
in der `drawer.py` erst das L-System mithilfe von `DrawerSimulation` simulieren.
|
|
Anschließend wird die Startpostion der Schildkröte, sowie Länge mit der sie sich
|
|
fortbewegt, so gewählt, dass sich die Zeichnung im vorgesehenen Bereich
|
|
befindet. Mit diesen Werten wird es mit der Klasse `Drawer` gezeichnet.
|
|
Schließlich werden die Einstellungen, mit denen das L-System gezeichnet wurde,
|
|
in der Liste `drawings` abgespeichert.
|
|
|
|
In der `__main__.py` werden zunächst einige Einstellungen vorgenommen und die
|
|
Funktion `takeInput` in `inputHelper.py` aufgerufen. Diese nimmt einen Befehl
|
|
entgegen und ruft sich danach rekursiv auf. Beim d(raw) Befehl wird nach dem zu
|
|
zeichnenden L-System und verschiedenen Einstellungen gefragt. Dazu werden
|
|
diverse Hilfsfunktionen für unterschiedliche Eingabetypen z. B. Zahlen und
|
|
Zeichenketten benutzt. Zuletzt wird gefragt, ob das L-System das ganze Fenster
|
|
ausfüllen soll. Wird dies verneint, kann der Nutzer durch Klicken auf die
|
|
diagonalen Eckpunkte, die Position und Größe der Zeichnung eingeben. Schließlich
|
|
wird die `draw` Funktion aufgerufen.
|
|
|
|
Eine Zeichnung kann auch wieder mit der `delete` Funktion der `drawer.py`
|
|
gelöscht werden, da jedes L-System mit einer neuen Schildkröte gezeichnet wird.
|
|
So kann eine Zeichnung durch den Aufruf der `clear` Methode der Schildkröte
|
|
gelöscht werden.
|
|
|
|
Außerdem kann der Zustand des Programms mit allen Zeichnungen und der gewählten
|
|
Hintergrundfarbe abgespeichert und wieder geladenen werden. Hierfür wird die in
|
|
Python integrierte pickle Library verwendet.
|
|
|
|
Das Bild kann auch als Bilddatei exportiert werden. Dafür wird eine Funktion von
|
|
Tk benutzt, mit der man das Bild im Postscript Format erhält. Mit der PIL kann es
|
|
dann in verschiedensten Bildformaten abgespeichert werden.
|
|
|
|
## Quellen
|
|
|
|
[https://de.wikipedia.org/wiki/Lindenmayer-System](https://de.wikipedia.org/wiki/Lindenmayer-System),
|
|
aufgerufen am 14. Januar 2022 um 16:12 Uhr
|