Die Grundidee unseres Projekts Tree Generator war, unter Zuhilfenahme von OpenGL ein Programm-Modul zu erstellen, das in der Lage ist, mittels zahlreicher Parameter nahezu beliebige Bäume zu generieren. Dabei sollte ein guter Mittelweg zwischen Realismus und einfachem Aufbau gefunden werden, da die Bäume für Landschaftsdarstellungen in einer Virtual Reality-Umgebung bestimmt sind. Dies ist auch der Grund, warum beschlossen wurde, die Bäume als Triangle Strip-Sets aufzubauen; unser Betreuer versicherte uns, daß dies die beste Voraussetzung für schnelle Darstellungsgeschwindigkeiten wäre.
Als Ausgangspunkt diente der Artikel Creation and rendering of Realistic Trees*, der uns Einblicke in grundsätzliche Möglichkeiten zur Baumgenerierung gewährte. Aufgrund unseres Baumaufbaus (die Triangle Strip-Sets zwangen uns zu spiralförmig aufgebauten Ästen) konnten wir uns, insbesondere was die erforderlichen Parameter anbelangte, jedoch nicht sehr stark an den Artikel anlehnen, sondern mußten eigene Wege gehen.
* Weber, Jason und Penn, Joseph: Creation and Rendering of Realistic Trees; in Computer Graphics Proceedings, Annual Conference Series, SIGGRAPH 95, Los Angeles, California, August 6-11, 1995
Die folgenden Parameter werden (optional) von einem
angegebenen Baumdatenfile eingelesen. Dabei muß folgende Form verwendet
werden:
Parametername=Wert
Für jeden Parameter ist eine eigene Zeile
zu verwenden, für nicht angegebene Parameter werden default-Werte
verwendet. Die Reihenfolge der Parameter kann beliebig sein, kommt derselbe
Wert mehrmals vor, wird sein erstes Vorkommnis beachtet. Groß- und
Kleinschreibung sind zu beachten!
Zur besseren Lesbarkeit wird in diesem Text das
Dezimalkomma verwendet, im Datenfile muß der bei Computern übliche
Dezimalpunkt verwendet werden.
Siehe auch Datenfile-Beispiel.
Die unter "Sinnvolle Werte" angegebenen Zahlen gehen von dem aus, was im Allgemeinen unter den Begriff "Baum" fällt, und sind daher gut als Richtlinien geeignet.
Bei einigen Parametern sind auch Werte außerhalb
des unter "Sinnvolle Werte" angegebenen Intervalls zulässig. Beachten
Sie jedoch, daß die Werte nicht auf Ihre Gültigkeit geprüft
werden.
Ungeeignete Werte können zu unerwarteten Effekten
und Programmabstürzen führen.
Setzt den Zufallsgenerator. Geben Sie 0 an, wenn Sie einen zufälligen Wert erhalten wollen.
Sinnvolle Werte: Seed>=0
Default: 0
Anzahl der Punkte, aus denen eine volle Umdrehung der Spiralen besteht. Ein Streifen der Spirale besteht aus Dreiecken mit Steps*2 Punkten (je 2 Punkte liegen übereinander). Dieser Wert bestimmt also die Auflösung (die Anzahl der Punkte), mit der der Baum generiert wird.
Sinnvolle Werte: 3<Steps<20
Default: 10
Steps=3
Steps=15
Bestimmt die Grundform des Baumes.
Prozentualer Anteil des Stammes, der die Größe des Bereiches ohne Äste am Fuß des Stammes angibt. Bsp.: Bei BaseSize=0,5 werden nur in der oberen Hälfte des Stammes Äste generiert. Siehe auch BaseSize1 und BaseSizeL.
Sinnvolle Werte: 0<BaseSize<1
Default: 0,4
BaseSize=0,5
BaseSize=0,7
Scale
Die zugrundeliegende Größe, an der sich alle Length-Parameter orientieren.
Sinnvolle Werte: Scale<0
Default: 10
Beginn- und Endradius des Stammes. Dies ist eine absolute Größe (wie Scale). Die Radien von Ästen orientieren sich am Radius der Stelle, von der sie ausgehen. Der Endradius sollte nicht zu groß gewählt werden, da man sonst in den Stamm hineinschauen kann.
Sinnvolle Werte: 0,1<=StartRad0; 0,1<=EndRad0<=1
Default: 0,2; 0,1
StartRad0=0,2
EndRad0=0,1
StartRad0=0,35
EndRad0=0,2
Length0
Länge des Stammes (=Baumhöhe). Prozentuelle Angabe bezüglich Scale.
Sinnvolle Werte: 0<=Length0<1
Default: 1
Length0=1
Length0=0,5
Anzahl der "Teile", also Spiralumdrehungen, aus denen der Stamm besteht. Der Stamm kann an maximal CurveRes0-1 Stellen Knicke aufweisen. Sollte CurveRes0 so klein gewählt werden, daß die Streifenhöhe strheight (ein derzeit nicht veränderbarer Wert) übersteigt, werden zusätzliche Spiralumdrehungen eingefügt, um genügend Ansatzpunkte für Äste zu bieten. Die Anzahl der Knicke wird dadurch aber nicht beeinflußt.
Sinnvolle Werte: 1<=CurveRes0<=20
Default: 8
Wert zur Festlegung des Maximums des zufallsgesteuerten
Knickwinkels des Stammes. Abw0 ist indirekt proportional zum maximalen
Knickwinkel! (Abgesehen vom Wert 0)
Um sinnvolle Werte zu bestimmen, beachte man die
starke Abhängigkeit zu CurveRes0.
0=Kein Knick, also gerader Stamm
1=Knicke haben max. 90 Grad
...
100=Knicke haben max. 5 Grad
Sinnvolle Werte: Abw0>=20
Default: 100
Abw0=100
Abw0=20
StartRadDiv
Dieser Parameter beeinflußt die Startradien
aller Äste ab Level 1 (alle außer dem Hauptstamm). Der Startradius
eines Astes errechnet sich aus dem Radius des Parent-Astes (oder Stammes)
an der Stelle, an der der neue Ast entspringt, dividiert durch StartRadDiv.
Ist dieser Wert 1, ist der Startradius des neuen Astes also gleich dem
Radius des Parents an der Wuchsstelle.
Es wird jedoch empfohlen, Werte über 1 zu
verwenden, da ansonsten unschöne Übergänge entstehen können.
Sinnvolle Werte: 1<=StartRadDiv<3
Default: 2
StartRadDiv=1
StartRadDiv=2
EndRadDiv
Definiert den Endradius jedes Astes ab Level 1
(alle außer Hauptstamm) in Abhängigkeit von dessen Startradius.
Der Enradius berechnet sich also so: Startradius/EndRadDiv. Um Äste,
die außen dicker sind als innen und solche, in die man hineinsieht,
zu vermeiden, sollte auch dieser Wert größer als 1 gewählt
werden.
Sinnvolle Werte: 1<EndRadDiv<3
Default: 2
Anmerkungen zu den Astradien
Beachten Sie, daß letztendlich alle Radien
auf der Dicke des Hauptstammes, definiert durch StartRad0
und EndRad0, basieren.
Ebenfalls interessant in diesem Zusammenhang: Der
minimale zulässige Radius ist 0,03 (um Darstellungsfehler zu vermeiden).
Wird durch die Wahl der Parameter dieser Wert unterschritten, wird 0,03
verwendet, was dazu führt, daß ab diesem Punkt die Äste
zylindrisch sind.
Werden jedoch große Radien in Verbindung
mit stark geknickten Ästen und geringer Auflösung (siehe Steps)
verwendet, verwinden sich die Äste an den Knickstellen und erscheinen
daher dort dünner.
Prozentualer Anteil aller Level 1-Äste, an dem keine Level 2-Äste wachsen. Beispiel: Bei BaseSize1=0,3 wachsen nur an den äußeren 70% der Level 1-Äste Level 2-Äste, die inneren 30% bleiben leer. Siehe auch BaseSize und BaseSizeL.
Sinnvolle Werte: 0<BaseSize1<1
Default: 0,2
Gibt den Winkel von Level 1-Ästen zum Hauptstamm an. Bei einem Wert von 90 Grad stehen die Äste parallel zum "Boden", bei Werten unter 90 sind sie nach oben, bei Werten über 90 nach unten orientiert.
Sinnvolle Werte: 10<=DownAngle1<=150
Default: 90
DownAngle1=50
DownAngle1=80
Rotate1
Definiert den Richtungsunterschied zwischen zwei aufeinanderfolgenden Level 1-Ästen. Bei einem Wert von 0 zeigen alle Äste in dieselbe Richtung.
Sinnvolle Werte: 10<=Rotate1<=350
Default: 140
Rotate1=90
Rotate1=140
Definiert (analog zu Abw0) die Knickwinkel der Level 1-Äste.
Sinnvolle Werte: Abw1>=20
Default: 50
Anzahl der Level 1-Äste, die vom Hauptstamm ausgehen.
Sinnvolle Werte: 1<=Branches1<=100
Default: 60
Branches1=20
Branches1=50
Maximallänge der Level 1-Äste, prozentualer Anteil von Scale. Die tatsächliche Astlänge wird wesentlich durch Shape beeinflußt.
Sinnvolle Werte: 0<Length1<=1
Default: 0,5
Length1=0,3
Length1=0,7
Anzahl der Spiralumdrehungen, aus denen Level 1-Äste bestehen, siehe CurveRes0.
Sinnvolle Werte: 1<=CurveRes1<=20
Default: 10
DownAngle2
Gibt den Winkel von Level 2-Ästen zu Level 1-Ästen an.
Sinnvolle Werte: 10<=DownAngle2<=100
Default: 45
Rotate2
Definiert den Richtungsunterschied zwischen zwei aufeinanderfolgenden Level 2-Ästen. Bei einem Wert von 0 zeigen alle Äste in dieselbe Richtung.
Sinnvolle Werte: 10<=Rotate1<=350
Default: 45
Abw2
Definiert (analog zu Abw0 und Abw1) die Knickwinkel der Level 2-Äste.
Sinnvolle Werte: Abw2>=20
Default: 30
Anzahl der Level 2-Äste pro Level 1-Ast.
Sinnvolle Werte: 1<=Branches2<=50
Default: 17
Length2
Maximallänge der Level 2-Äste, prozentualer Anteil von Scale. Die tatsächliche Astlänge wird wesentlich durch Shape und Length1 beeinflußt.
Sinnvolle Werte: 0<Length2<=1
Default: 0,2
CurveRes2
Anzahl der Spiralumdrehungen, aus denen Level 2-Äste bestehen, siehe CurveRes0 und CurveRes1.
Sinnvolle Werte: 1<=CurveRes2<=20
Default: 2
Prozentualer Anteil aller belaubten Äste (Äste, deren Level>=LeafLevel ist), an dem keine Blätter wachsen. Beispiel: Bei BaseSizeL=0,4 wachsen nur an den äußeren 60% der belaubten Äste Blätter, die inneren 40% bleiben unbelaubt. Siehe auch BaseSize und BaseSize1.
Sinnvolle Werte: 0<BaseSizeL<1
Default: 0,1
Leaves
Die Anzahl der Blätter pro Ast, dessen Level größer oder gleich LeafLevel ist. Diese Blätter werden seitlich am Ast angebracht.
Sinnvolle Werte: Leaves>=0
Default: 2
Leaves=0
Leaves=20
Gibt an, ob sich an den Spitzen der Äste, deren Level größer oder gleich LeafLevel ist, Blätter befinden. Diese Blätter werden jedoch nur dann generiert, wenn Leaves größer Null ist.
Sinnvolle Werte:
Leaves1=0: Keine Blätter an den Astspitzen
Leaves1=1: Blätter an den Astspitzen
generieren (wenn Leaves>0)
Default: 0
LeafLevel
Gibt den Level der Äste an, ab dem Blätter generiert werden.
Sinnvolle Werte: 0<=LeafLevel<3
Default: 2
LeafLevel=1
LeafLevel=2
LeafScale
Länge des Blattes (absoluter Wert).
Sinnvolle Werte: LeafScale>0
Default: 0,3
LeafScaleAbw
Standardabweichung der Blattlänge.
Sinnvolle Werte: 0<=LeafScaleAbw<LeafScale
Default: 0,03
LeafScaleX
Breite des Blattes relativ zu LeafScale.
Sinnvolle Werte: 0<LeafScaleX<=1
Default: 0,5
LeafShape
Bestimmt die Form der Blätter. Bei einem durchschnittlich belaubten Baum reduziert sich die Anzahl der Dreiecke auf ein Drittel, wenn statt der sechseckigen die dreieckige Blattform gewählt wird.
Neigungszuwachs des Blattes in Grad, d.h. der Wert, der zur Neigung des Astes, an dem das Blatt wächst, addiert wird. Auch negative Werte sind möglich, dann steht das Blatt nach oben. Bei positiven Werten hängt das Blatt nach unten.
Sinnvolle Werte: -90<LeafAngleX<90
Default: 10
LeafAngleXAbw
Standardabweichung von LeafAngleX in Grad.
Sinnvolle Werte: 0<=LeafAngleXAbw<10
Default: 2
Winkel in Grad, in dem das Blatt vom Ast, an dem es wächst, absteht (von oben gesehen). Ob das Blatt rechts oder links wegwächst, wird zufällig bestimmt.
Sinnvolle Werte: 0<LeafAngleZ<180
Default: 50
LeafAngleZAbw
Standardabweichung von LeafAngleZ in Grad.
Sinnvolle Werte: 0<=LeafAngleZAbw<30
Default: 5
Definiert die Blattfarbe, z.B.: LeafColor=0.1 0.8 0 (RGB-Werte durch Leerzeichen getrennt).
Sinnvolle Werte: zwischen 0 und 1 für jeden
Farbanteil
Default: 0 0,6 0
LeafColor=0,1
0,5 0,15
LeafColor=0,7
0,7 0,5
Gibt das Maximum der zufälligen Farbabweichung der Blätter von LeafColor an, und zwar einzeln für jeden Farbanteil, z.B.: LeafColorV=0 0.2 0, in diesem Fall weicht der Grünanteil der Blattfarbe um maximal +/-0,2 vom Grünanteil in LeafColor ab.
Sinnvolle Werte: zwischen 0 und 1 für jeden
Farbanteil
Default: 0,1 0,1 0,1
LeafColorV=0,1
0,2 0,2
LeafColorV=0,6
0,6 0,5
Definiert die Stammfarbe (analog zu LeafColor).
Sinnvolle Werte: zwischen 0 und 1 für jeden
Farbanteil
Default: 0,6 0,5 0,3
Definiert die Farbabweichung für Äste (analog zu LeafColorV).
Sinnvolle Werte: zwischen 0 und 1 für jeden
Farbanteil
Default: 0,02 0,02 0,02
Folgendes Beispiel eines Datenfiles generiert eine
Pinie mit Blättern in unterschiedlichen Herbstfarben. Die Reihenfolge
der Parameter ist beliebig, Groß- und Kleinschreibung sind jedoch
einzuhalten! Für alle nicht spezifizierten Parameter werden die Default-Werte
verwendet. Da kein fixer Seed gegeben ist,
erhält man bei jedem Aufruf einen Baum mit einem etwas anderen Aussehen.
Wie Sie sehen, genügt bereits die Angabe weniger
Parameter für die Generierung eines recht spezifischen Baumes.
Steps=8
Shape=6
BaseSize=0.7
Abw0=60
DownAngle1=85
Branches1=40
Length1=0.4
Branches2=10
Leaves1=1
LeafAngleX=20
LeafAngleZ=75
LeafColor=0.6 0.7 0
LeafColorV=0.2 0.2 0.2
StemColor=0.5 0.5 0.3
StemColorV=0.03 0.03
0.02