14 Baum des Pythagoras
Contents
Nachdem wir letzte Woche das Mandelbrot und Julia-Mengen gemalt haben, wollen wir heute weitere Fraktale produzieren.
Das Ziel
0. Programm aufsetzen
Das kennst du schon: Ein neues Kotlin-Projekt anlegen und das Hauptprogramm ausfüllen, etwa so:
|
|
1. Komponente zum Malen
Auch diesen Teil solltest du schon einmal gesehen haben. Wir fangen etwa so an:
|
|
Die Verwendung von scale
sollte dir bekannt vorkommen: Zum Malen müssen wir stets die vituellen Koordinaten in Bildschirm-Koordinaten umrechnen. Dazu legen wir einen gemeinsamen Skalierungsfaktor in $x$- und in $y$-Richtung fest und zentrieren die Ausgabe. Um 2 virtuelle Punkte zu einer Linie auf dem Bildschirm zu verbinden, gibt es die Methode drawLine
.
Die Klasse Square
beschreibt die Größe des Basiselementes. Dieses besteht aus einem Quadrat (engl. square). Das wiederum besteht aus dem linken unteren Punkt sowie der Richtung der ersten Seite (dx
Schritte nach rechts und dy
Schritte nach oben). Wir fangen mit einer Standardgröße an, die nur 12.5% des Bildschirms (in jeder Richtung) füllt.
2. Das Basiselement
Wenn wir uns das Zielbild anschauen, erkennen wir, dass der Baum aus einer wiederholten Konstruktion des folgenden Elements besteht:
Genau damit fangen wir in der Methode branch
(engl. für Zweig/verzweigen) an. Das Stück Stamm ist ein Quadrat, d.h. alle 4 Seitenlängen sind gleichgroß und wir müssen über der gegebenen unteren Seite eine linke, eine obere und eine rechte Seite malen (braune Linien). Dazu ergänzen wir 2 weitere Punkte p2
und p3
in der Definition von Square
.
|
|
Dann setzt ein Verzweigungselement auf dem Stück Stamm auf. Das besteht aus einem rechtwinkligen Dreieck. Das einfachste rechtwinklige Dreieck, welches mir einfällt, hat Seitenlängen 3, 4 und 5. D.h. die längste Seite (Hypothenuse) hat Länge 5 und die beiden anderen Seiten Längen 3 und 4, entsprechend. Damit ist tatsächlich $3^2+4^2=9+16=25=5^2$, also ist es ein rechtwinkliges Dreieck.
Wo liegt nun die Spitze?
Die Seite vom linken-oberen Punkt des Quadrates zur Spitze hat die Länge $0.8l$, wobei $l$ die Länge der Seite des Quadrates ist. Wenn das Quadrat $\Delta x$ breit ist, müssen wir $x_0$ um $0.8\cdot0.8\Delta x$ verschieben. Wenn die Grundseite noch um $\Delta y$ rechts angehoben ist, dann muss man die $x$-Koordinate noch um $-0.8\cdot0.6\Delta y$ korrigieren.
Die $y$-Koordinate ist $0.6$ von der Dreiecksseiten-Länge, also $0.8\cdot0.6\Delta x$, wenn die Seite waagerecht liegt. Wenn die Grundseite noch um $\Delta y$ rechts angehoben ist, dann muss die Spitze um $0.8\cdot0.8\Delta y$ zusätzlich angehoben werden.
Insgesamt zeichnet man das Verzweigungselement mittels
|
|
3. Iterum, Iterumque (Wieder und wieder)
Wie kommt man jetzt zu dem gesamten Baum? Dazu muss man auf dem Zweig 2 Zweigelemente aufsetzen. Das kann man wie folgt erreichen:
|
|
Die unteren 2 Zeilen malen je Element 2 Kind-Elemente, eines nach links und eines nach rechts. Die obere Zeile braucht man, da sonst das Malen nie fertig wird (unendliche Rekursion). Die Abbruchbedingung ist, dass das Element zu klein ist, um es noch zu sehen.
4. Variationen
4.1 hellbraune Zweige und grüne Blätter
Das kann man dadurch erreichen, dass man bei Eintritt in die branch
-Methode die Malfarbe entsprechend der aktuellen Größe setzt, also etwa so
|
|
4.2 Zufällige Drehung
Diese kann man erreichen, indem man den Dreieckspunkt wahlweise nach links oder nach rechts verschiebt. Die Koordinaten zur Verschiebung nach links lauten: $0.6(0.6\Delta x-0.8\Delta y)$, $0.6(0.8\Delta x+0.6\Delta y)$.
Die zufällige Flunktuation kann man erreichen, indem man
|
|
4.3 Weniger Zweige
Das kann man erreichen, indem man den 2. (kleineren) Zweig nur manchmal einfügt, z.B. so
|
|
9. Selber Probieren
Jetzt bist du dran. Funktioniert das Programm bei dir? Falls nicht, schau doch mal auf die Fehlermeldung, vielleicht bekommst du wenigstens heraus, wo der Fehler ist. Dann musst du die entsprechende Stelle verstehen und korrigieren.
Kannst du den Baum so abändern, dass der Stamm-Bereich (size2>=twigSize2
) grau-braun ist?
9.2 Anderes Dreieck
Was passiert, wenn du die Seitenverhältnisse des Dreiecks auf 12.0/13
und 5.0/13
änderst? (Eventuell musst du das Anfansquadrat noch etwas nach rechts verschieben.)
9.3 3 Zweige
Was müsstest du ändern, damit nicht 2 Zweige, sondern 3 Zweige von jedem Stammstück abgehen?
Hinweis: Offenbar muss der rekursive Aufruf am Ende 3-mal kommen. Welchen 2. Stützpunkt kann man wählen?
Viel Spaß beim Probieren.