Wir können Flächen sowohl durch die Beschreibung von Gebieten im Parameterbereich als auch durch die Angabe von Volumina im Raum der Fläche trimmen. Haben wir dann eine Testfunktion, mit der wir überprüfen können, ob die Parameter bzw. die Bildpunkte innerhalb oder außerhalb dieser Bereiche liegen, können wir die getrimmten Flächen darstellen.
Eine einfache, leicht zu implementierende Methode die Fläche im Raum mit Hilfe von Volumina zu trimmen, besteht in der impliziten Beschreibung der Volumina. Wir beschränken uns dazu auf die quadratische Form
Im Parameterbereich geben wir die Trimmbereiche über Trimmkurven an. Diese schneiden Teile des Parameterbereiches aus, die wir auf die Fläche übertragen. Eine solche Trimmkurve beschreiben wir durch die Klasse TrimCurve aus Abbildung 3.2. Eine Trimmkurve beschreibt einen Trimmbereich für ein einzelnes Bézierflächenstück der G-Spline-Fläche. Die Kurve kann entweder ein Polygonzug oder eine geometrisch glatte, quadratische Splinekurve sein. Der Parameterbereich sei wie üblich . Die Trimmkurve kann diesen Bereich aber verlassen.
Für einen Polygonzug legen die Kontrollpunkte die Ecken fest. Zwei aufeinanderfolgende Kontrollpunkte geben jeweils eine Linie des Polygonzuges an. Zusätzlich wird der erste und der letzte Punkt in der Kontrollpunktliste durch eine Linie miteinander verbunden. Der von diesem Polygonzug eingeschlossene Bereich wird aus dem Parameterbereich ausgeschnitten. Wir gehen dabei davon aus, daß der Polygonzug immer im Uhrzeigersinn durchlaufen wird und alles, was rechts vom Polygonzug liegt, ausgeschnitten wird. Einen Testalgorithmus, mit dem wir bestimmen können, ob ein Punkt im Parameterbereich ausgeschnitten wird, werden wir weiter unten vorstellen.
Geben die Kontrollpunkte eine quadratische Splinekurve an, dann gibt es pro Kontrollpunkt jeweils ein quadratisches Bézierkurvensegment. Die für dieses Segment notwendigen drei Bézierpunkte werden aus dem Kontrollpunkt und dem Kontrollpunkt vor und nach über die Bedingungen der geometrischen Stetigkeit berechnet. Ist der erste und letzte Kontrollpunkt identisch, dann ist die Kurve geschlossen. Ist die Kurve nicht geschlossen, dann erweitern wir die Kurve zunächst so, daß Anfangs- und Endpunkt sicher außerhalb des Parameterbereiches liegen und fügen Teile des Randes von hinzu, damit eine geschlossene Kurve entsteht. Die so erzeugte quadratische Kurve wandeln wir in einen Polygonzug um. Der eigentliche Testalgorithmus ist dann mit dem für die Polygonzüge identisch. Allgemein kann man natürlich eine Splinekurve von beliebigem Grad in einen Polygonzug umwandeln.
Abbildung 3.3 zeigt zwei Beispiele von Trimmkurven im Parameterbereich. Wir berücksichtigen dabei noch nicht den Umlaufsinn und mehrere Trimmkurven in einem Parameterbereich. Die linke Trimmkurve ist ein Polygonzug. Dieser kann auch außerhalb des Parameterbereiches fortgesetzt werden. Dies entspricht einer linearen Trimmkurve im Parameterbereich, die entsprechende Teile des Randes von enthält. Die rechte Trimmkurve wird durch eine Bézierkurve bestimmt. Sie ist nicht geschlossen und wird durch den Rand von erweitert. Wie dies genau geschieht wird im Algorithmus zur Umwandlung in einen Polygonzug beschrieben. Liegt der Anfangs- oder Endpunkt innerhalb des Parameterbereiches, verlängern wir zunächst die Kurve in Richtung der Tangente an den entsprechenden Punkt, bis wir den Parameterbereich verlassen haben. Danach verbinden wir den Eintritts- und Austrittspunkt der Kurve aus dem Parameterbereich über den Rand. Wir gehen dabei im Uhrzeigersinn vom Austrittspunkt zum Eintrittspunkt.
Die Umwandlung dieser Kurven in Polygonzüge und die Erweiterung durch den Rand des Parameterbereiches wird durch den Algorithmus process_quadratic_trimcurve behandelt. Er wandelt eine zwei-dimensionale quadratische Splinekurve mit n Kontrollpunkten b[0] b[n-1] in einen Polygonzug x[0] y[0] x[N-1] y[N-1] um. Dabei ist zu beachten, daß wir aus den Kontrollpunkten zunächst die Bézierpunkte für eine geometrisch glatte, quadratische Kurve berechnen. Für jedes quadratische Segment der Trimmkurve benötigen wir Linien, wenn step die Schrittweite zur Berechnung der quadratischen Kurve ist. Wenn wir die Kurve mit dem Rand von erweitern müssen, kommen noch maximal vier Ecken hinzu. Für die Punkte, an denen wir das Einheitsquadrat für die Erweiterung verlassen und eintreten, haben wir nochmal zwei zusätzliche Punkte für den Polygonzug. Insgesamt ist also nicht größer als .
process_quadratic_trimcurve |
Quadratische Trimmkurve in einen Polygonzug umwandeln |
Nun fehlt noch der oben angesprochene Testalgorithmus für einen Polygonzug. Diese Testfunktion muß überprüfen, ob ein vorgegebener Punkt u v im Parameterbereich durch die Trimmkurve ausgeschnitten wird. Die Trimmkurve ist dabei als Polygonzug über die beiden Arrays x und y gegeben. Der Umlaufsinn, mit dem die Trimmkurve durchlaufen wird, gibt normalerweise an, welcher Bereich innerhalb des Trimmbereiches liegt und welcher außerhalb. Wir nehmen im folgenden immer an, daß der Polygonzug im Uhrzeigersinn durchlaufen wird und alles, was rechts von dem Polygonzug liegt, ausgeschnitten wird. Gebiete mit entgegengesetztem Umlaufsinn können durch die Kombination mehrerer Trimmkurven erzeugt werden. Wir werden dies weiter unten genauer betrachten.
Zum Testen, ob ein Punkt im Trimmbereich liegt, zählen wir im Algorithmus trimcurve_test, wie oft eine Linie von u v in Richtung den Polygonzug schneidet. Ist die Anzahl der Schnitte gerade, sind wir außerhalb des Trimmbereiches, sonst innerhalb. Die Richtung ist dabei beliebig. Ein paar Beispiele hierfür zeigt Abbildung 3.5. Ist der Punkt innerhalb des Trimmbereiches, muß die Linie wenigstens einmal den Rand schneiden. Tritt die Linie an einer anderen Stelle wieder in den Trimmbereich ein, dann muß sie diesen auch wieder verlassen, da er beschränkt ist. Damit ist die Anzahl der Schnitte ungerade. Liegt der Punkt dagegen außerhalb des Trimmbereichen, dann gibt es für jeden Eintrittspunkt in den Trimmbereich auch wieder einen Austrittspunkt und so ist die Anzahl der Schnitte gerade. Es gibt allerdings Fälle, wie für den nicht ausgefüllten Punkt in Abbildung 3.5, bei denen dieses Verfahren nicht funktioniert. Durch zusätzliche Tests, etwa das Zählen der Schnitte mit Linien in andere Richtungen, lassen sich solche Fälle weitere reduzieren, wir gehen hierauf aber nicht näher ein. Für unsere Zwecke genügt die einfache Variante, wobei es manchmal nötig sein kann die Auflösung der Testgitter und der Trimmkurven anzupassen.
trimcurve_test |
Testfunktion für eine lineare Trimmkurve |
Wir beschreiben nun den Algorithmus zum Zeichnen getrimmter G-Spline-Flächen. Die Umwandlung in Bézierkontrollnetze ändert sich dabei nicht. Die impliziten Funktionen zum Trimmen im Raum der Fläche geben wir allgemein für die Fläche an. Für die Trimmkurven müssen wir dagegen auch das Bézierflächenstück festlegen. Nachdem wir nur biquadratische Flächenstücke haben, genügt es für die Trimmkurven einen G-Spline-Kontrollpunkt anzugeben. Dieser bestimmt dann das Flächenstück. Im Algorithmus zeichnen wir jedes Bézierflächenstück einzeln. Wir verwenden dazu die oben vorgestellten
Testfunktionen. Zusätzlich müssen wir allerdings berücksichtigen, daß mehrere Trimmkurven und implizite Funktionen für ein Flächenstück angegeben werden können. Dabei gehen wir davon aus, daß implizite Funktionen immer Teile aus der Fläche ausschneiden, auch wenn die Volumina sich überlappen.Bei Trimmkurven können sich dagegen auch “Inseln” bilden. Liegt ein Punkt im Parameterbereich innerhalb einer geraden Anzahl von Trimmbereichen, dann wird er nicht ausgeschnitten. Liegt er in einer ungeraden Anzahl von Trimmbereichen wird er ausgeschnitten (vgl. Abbildung 3.8). Damit entstehen keine Probleme, wenn sich die Trimmkurven schneiden oder der Umlaufsinn der Trimmkurven nicht zusammenpaßt. Eigentlich ignorieren wir den Umlaufsinn einfach. Deshalb nehmen wir auch wie oben beschrieben immer an, daß die Trimmkurven im Uhrzeigersinn durchlaufen werden. Trimmkurven, die gegen den Uhrzeigersinn durchlaufen werden, lassen sich trotzdem modellieren. Soll z.B. alles, was außerhalb eines Kreises im Parameterbereich liegt, weggeschnitten werden, genügt es den Rand von zusätzlich zum Kreis als Trimmkurve anzugeben.
trimmed_bezier |
Zeichnen eines getrimmten Bézierflächenstückes |
trimmed_bezier wird mit einer Liste der Trimmkurven aufgerufen, die zu dem jeweiligen Bézierflächenstück gehören. Diese Liste kann über den zu jeder Trimmkurve angegebenen Kontrollpunkt der
G-Spline-Fläche bestimmt werden. Beim ersten Aufruf wählen wir normalerweise das Einheitsquadrat als Parameterbereich und die Rekursionstiefe ist 0. Das Trimming wird im Algorithmus vor allem durch I. implementiert. Dieser Teil kann in ähnlicher Form auch in den anderen Algorithmen für getrimmte Flächen verwendet werden.Bei trimmed_bezier ist zu berücksichtigen, daß die Auflösung für das Testgitter groß genug gewählt wird. Ansonsten ist es möglich, daß kleine Trimmbereiche ausgelassen werden. Auf der anderen Seite sollte aber vor allem die maximale Rekursionstiefe klein sein, da sonst der Algorithmus am Rand der Trimmbereiche sehr lange arbeitet. Die maximale Rekursionstiefe sollte der benötigten Grafikauflösung für die Darstellung angepaßt sein.
Die Trimmkurven können wir nicht für Flächen verwenden, auf die der Doo-Sabin-Subdivision-Algorithmus angewendet wurde. In unserer Implementierung des Doo-Sabin-Subdivision-Algorithmus' wird das alte Kontrollnetz vollständig durch ein neues ersetzt. Da die Trimmkurven an die alten Kontrollpunkte gebunden sind, verlieren wir hierbei alle Trimmkurven. Wir gehen in dieser Arbeit nicht näher auf dieses Problem ein, es wäre allerdings sinnvoll eine Übertragung der Trimmkurven auf die neuen Kontrollpunkte zu entwickeln. In diesem Zusammenhang sollte man auch eine Methode einführen, Trimmkurven über mehrere Parameterbereiche anzugeben. Implizite Funktionen können dagegen auch für Flächen zusammen mit der Doo-Sabin-Subdivision verwendet werden.
Abbildung 3.7 zeigt das Kreuz aus Abbildung 1.23, aus dem über eine implizite Funktion eine Kugel ausgeschnitten wurde. In Abbildung 3.9 zeigen wir den Würfel aus Abbildung 1.19, bei dem drei zu den Koordinatenachsen parallele Zylinder ausgeschnitten wurden.
Abbildung 3.10 stellt eine G-Spline-Fläche mit einer Irregularität der Ordnung dar, bei der jeder Kontrollpunkt an der Irregularität mit jeweils drei quadratischen, nicht geschlossenen Trimmkurven und einem Trimmpolygon versehen wurde.
|
|