Übersicht

Kissenpflanze

Demodatei: Demo4.pov

Für den Aufbau unserer Kissenpflanze werden wir wiederum Positionen verwenden, die zufällig innerhalb eines Objekts verteilt sind. Dieses Mal handelt es sich bei dem Objekt aber nicht um eine Kugel, wie in Kapitel 2, sondern um Kugelschalen unterschiedlicher Größe. Die Sphere_Sweeps für die Kissenpflanze werden aus den Punkten von insgesamt 5 konzentrisch übereinanderliegenden Kugelschalen konstruiert werden. Die Sphere_Sweeps werden jeweils an einem Punkt der äußersten Schale beginnen und jeweils zum nahegelegensten Punkt der nächstkleineren Schale nach innen wandern, bis sie den Mittelpunkt der Schalen erreicht haben. Die folgenden Abbildungen zeigen zwei solcher Schalen (links), diese Schalen und einen Sphere_Sweep (definiert mit Hilfe der Positionen aus 5 Schalen, Mitte) und die Gesamtheit aller Sphere_Sweeps für alle Punkte der äußersten Schale (rechts). Unterhalb dieser Abbildung, wird die fertiggestellte Kissenpflanze gezeigt. Dieses Modell ist sicher nicht perfekt: An vielen Stellen existieren zu viele Seitenäste und die inneren Äste sind nicht einheitlich genug, da für den Sphere_Sweep cubic spline und nicht linear spline verwendet wurde. Trotzdem ist die Art der Verzweigung auch nicht schlecht und das Beispiel zeigt, was man mit ein paar Punkten und einem Sphere_Sweep erreichen kann.

random bowls random bowls and on sphere_sweep random bowls and many sphere_sweeps a cushion plant

Ich beginne die Erklärung der Programmierung dieses Modells mit der Definition der Kugelschalen und mit der Anwendung eines Makros, der bereits in einem vorangehendem Kapitel eingeführt wurde. Dieser Makro erzeugt zufällige Positionen innerhalb eines Objekts und speichert diese Positionen in einem Array.

//Zunächst wird eine Kugelschale definiert.

#declare Bowl1 = difference {
sphere { <0, 0, 0>, 1.5 }
sphere { <0, 0, 0>, 1.0 }
}

//Nun kommt der Makro, um die Schale mit Positionen zu füllen.

xyzDistributionInsideArray (Bowl1, <-2, 0, -2>, 6, 4, 6, 0.75, 0.75, 0.75, 0.3)

Die obigen Zeilen definierten lediglich die innerste Schale unseres Beispiels. Die übrigen Schalen werden auf sehr ähnliche Art und Weise definiert. Die Parameter der Makros müssen den jeweiligen Schalen natürlich angepasst werden. Da wir die Prozedur wiederholt ablaufen lassen, müssen wir die Ausgabevariablen der Makros jeweils umbenennen.

#declare Sum1 = Sum;
#declare Positions1 = array[Sum1];
#declare Positions1 = Positions;

Nun müssen wir aus den verschiedenen Schalen Positionen für unsere Sphere_Sweeps auswählen. Wie so oft zuvor werden wir auch dieses Mal die Punkte in einem Array speichern, bevor wir die Sphere_Sweeps tatsächlich darstellen. In diesem Fall umfassen die Arrays 8 Elemente (5 Positionen aus den 5 verschiedenen Schalen, den Mittelpunkt der Schalen und zwei äußere Positionen, die nicht dargestellt werden).

#declare SweepPositions = array [8];

Für jeden Sphere_Sweep beginnen wir die Konstruktion an einer Position der äußersten Schale (in diesem Fall ist diese Position das erste Element des entsprechenden Arrays "Positions5").

#declare PEnd = Positions5 [0];

Während dies das eine Ende des Sphere_Sweeps darstellt, ist der Mittelpunkt der Schalen das andere Ende. Zusätzlich gibt es noch zwei äußere Punkte, die nicht mit dargestellt werden.

#declare SweepPositions[0] = <0, -0.5, 0>;
#declare SweepPositions[1] = <0, 0, 0>;
#declare SweepPositions[6] = PEnd;
#declare SweepPositions[7] = PEnd + (1/10*PEnd);

Um die Positionen aus den anderen Schalen zu finden, starten wir bei der äußersten Schale (PEnd, ein Punkt aus bowl5) und suchen nach dem nahegelegensten Punkt zu dieser Position in bowl4. Diese Position wird in unseren Array für den Sphere_Sweep übernommen und wird verwendet, um nun nach dem nahegelegensten Punkt in bowl3 zu suchen (etc...)

//Zunächst werden ein paar Variablen definiert: PStart speichert die Ausgangsposition,
//POpt speichert später die gesuchte Position,
//und Distance speichert den Abstand zwischen den Positionen
//aus den beiden Schalen.


#declare POpt = <0, 0, 0>;
#declare PStart = PEnd;
#declare Distance = 4;
#declare ticker2 = 0;

//Diese Schleife sucht nach einer Position in bowl4 mit dem kürzesten Abstand zu der Ausgangsposition in bowl5.

#while (ticker2 <Sum4)
#declare PTest = Positions4[ticker2];
#if (vlength(PStart-PTest) < Distance)
#declare POpt = PTest;
#declare Distance = vlength(PStart-PTest);
#else
#end
#declare ticker2 = ticker2 + 1;
#end

//Schließlich wird die gefundene Position im Array für den Sphere_Sweep gespeichert.

#declare SweepPositions[5] = POpt;

Nachdem wir alle Positionen des Arrays SweepPositions auf die soeben skizzierte Art und Weise definiert haben, können wir den Sphere_Sweep darstellen. In diesem Fall lassen wir allerdings den Durchmesser des Sphere_Sweeps kontinuierlich abnehmen.
Bis zu diesem Punkt haben wir nur einen einzigen Sphere_Sweep konstruiert. Wenn wir den gesamten Prozess für jeden Punkt aus bowl5 wiederholen, gelangen wir zu einer kugeligen Struktur, deren Äste in jeder Position von bowl5 enden.

Übersicht