Neben der Darstellung durch Farben bzw. als Gitter oder Fläche über der Fläche können wir G-Spline-Funktionen auch durch Isolinien oder Niveaulinien darstellen. Dazu zeichnen wir auf der Fläche eine Linie, entlang der die Funktion den gleichen Wert hat. Die Werte, für die wir solche Linien zeichnen, können entweder äquidistant sein, oder wir können eine Liste spezieller Werte angeben.
Im Prinzip ist der Algorithmus für diese Darstellung ein
verallgemeinerter Plotter für Contourlinien einer Funktion
. Für die Isolinien leiten wir von Object eine neue
Klasse IsoLine ab, die Zeiger auf die Fläche und die Funktion
besitzt und die Darstellung der Isolinien genauer beschreibt, wie in
Abbildung 2.13 dargestellt. Wir gehen davon aus, daß
die Fläche und die Funktion bereits durch biquadratische
Bézierkontrollnetze beschrieben werden. Wieder bearbeiten wir jedes
Bézierkontrollnetz einzeln. Der Algorithmus isolines
zeichnet die Isolinien für das Bézierkontrollnetz fb der
Funktion, auf der durch das Bézierkontrollnetz b gegebenen
Fläche, für den Parameterbereich
u0
u1
v0
v1
. isolines wird rekursiv aufgerufen, um Unterschiede
in der Dichte der Linien auszugleichen. Dabei sollte aber die maximale
Rekursionstiefe möglichst klein gewählt werden. Der erste Aufruf
erfolgt natürlich für den Parameterbereich
.
isolines |
Isolinien Plotter |
Wie in Abbildung 2.15 gezeigt, unterteilen wir den Parameterbereich in Quadrate solange, bis nur noch maximal eine Linie durch jede Seite des Quadrats geht. Haben wir vorher die maximale Rekursionstiefe erreicht, dann legen wir über das Quadrat im Parameterbereich noch einmal ein Gitter, damit wir wieder Quadrate erhalten, durch deren Seiten maximal eine Linie geht. Das Gitter wird durch die Variablen aus Schritt refit:KuF:bilinf bestimmt. Es gibt zusätzlich den Parameter maxlines zur Begrenzung der Anzahl der Linien, die pro Quadrat des letzten Rekursionsschritts gezeichnet werden. Damit wird verhindert, daß hier ein zu feines Gitter erzeugt wird. Die Funktionswerte auf diesem Gitter werden durch bilineare Interpolation approximiert. Vor allem bei äquidistanten Isolinien für Funktionen, bei denen die Werte in einzelnen Bereichen stark ansteigen oder abfallen, aber sich sonst eher gering verändern, verbessert dies das Verhalten des Algorithmus'.
Die Interpolationsformel für die bilineare Interpolation von
auf dem Quadrat
bei Schritt I-C
im Algorithmus lautet
![]() |
(2.80) |
Die Linien für ein einzelnes Quadrat werden schließlich durch den Algorithmus handle_quad gezeichnet. Hier wird einfach überprüft, von welcher Seite des Quadrats zu welcher Seite wir eine Linie zeichnen müssen. Dazu wird das Quadrat zusätzlich in zwei Dreiecke aufgeteilt und der Schnittpunkt mit der Diagonalen berücksichtigt. Optional kann die Linie auch noch in der Farbe für den für sie vorgesehenen Funktionswert gezeichnet werden. Außerdem kann man die Linien längs der Einheitsnormalen der Fläche um einen festen Wert verschieben, um sicherzustellen, daß sie nicht von der Fläche überdeckt werden.
handle_quad |
Isolinien für ein einzelnes Teilquadrat zeichnen |
Wir zerlegen zunächst das Quadrat in zwei Dreiecke über die Diagonale von (u1,v0) nach (u0,v1). In beiden Dreiecken überprüfen wir dann, von welcher Seite zu welcher Seite wir eventuell eine Linie ziehen müssen. Diese Linie wird auf dem Bézierflächenstück der Fläche, welches zum Bézierkontrollnetz der Funktion gehört, zu den entsprechenden Parameterwerten gezeichnet. Falls eine Isolinie durch eine der Seiten im Parameterbereich geht, wird der genaue Parameterwert durch lineare Interpolation auf der Seite berechnet. In Abbildung 2.16 sind die drei Fälle für das Dreieck (u0,v0), (u1,v0), (u0,v1) dargestellt.
Der Test, ob durch eine Seite eine Isolinie geht, hängt von der Weise ab, wie die Funktionswerte für die Isolinien gegeben wurden. Verwenden wir äquidistante Linien, wird handle_quad bereits mit den auf ganzzahlige Werte verschobenen und skalierten Funktionswerten aufgerufen. Wir müssen dann nur noch überprüfen, ob zwischen zwei Funktionswerten eine ganze Zahl liegt. Für eine Liste von Funktionswerten ist dies nicht ganz so einfach. Hierfür müssen wir für jedes Element dieser Liste überprüfen, ob es zwischen den zwei Funktionswerten an den Ecken liegt. Wenn wir die Liste der Funktionswerte sortieren, können wir dabei ein paar Vergleiche einsparen.
Mit Hilfe des Isolinien-Algorithmus' können wir auch Contourplots erstellen. Dazu verwenden wir für die Kontrollpunkte der Fläche ein ebenes Gitter. Auf diesem Gitter geben wir die Funktionskontrollpunkte für den Contourplot an. Zeichnen wir die Isolinien für diese Funktion, erhalten wir einen Contourplot. So können wir die Funktionskontrollpunkte z.B. über die Parametrisierung des Affensattels
In Abbildung 2.19 stellen wir die
Funktion
auf der in
Abbildung 1.22 vorgestellten verdrehten Acht dar. Der
Ursprung liegt dabei “links hinten” in der Ecke des entsprechenden
erzeugenden Würfels. Ein Contourplot auf einer Ebene ist für diese
Funktion nicht mehr möglich.
Neben den Isolinien für Funktionen können wir sie auch für die Fläche selbst zeichnen, d.h. wir verwenden die Flächenfunktion selbst für Isolinien. In diesem Fall markieren die Isolinien die Kurven auf der Fläche mit konstantem Abstand vom Ursprung. Abbildung 2.20 zeigt dies für das in Abbildung 1.23 vorgestellte Kreuz. Der Ursprung wurde dabei in den Mittelpunkt des Kreuzes gelegt.
Interessanter sind aber Reflektionslinien. Dazu definieren wir
zunächst eine Ebene im Raum über einen Punkt und zwei linear
unabhängige Vektoren
und
. Auf dieser Ebene seien nun
parallele Lichtquellen im gleichen Abstand angebracht. In unserem
einfachen Modell sind die Lichtquellen unendlich lang und besitzen
keine Breite. Weiter nehmen wir an, daß die Intensität der
Lichtstrahlen unabhängig von der Entfernung immer gleich groß sei.
gebe die Richtung der Lichtquellen an und
sei der Abstand
zwischen den parallelen Lichtquellen. Das Licht von diesen
Lichtquellen reflektieren wir an der Fläche
für einen
vorgegebenen Beobachtungspunkt
. Diese Situation ist schematisch in
Abbildung 2.21 dargestellt.
Sei ein beliebiger Punkt auf
. Die Strecke
legt den
Ausfallswinkel für einen Reflektionsstrahl fest. Da der Einfallswinkel
genauso groß wie der Ausfallswinkel sein muß, erhalten wir die
Richtung
des Reflektionsstrahls aus
![]() |
(2.82) |
![]() |
(2.83) |
![]() |
(2.84) |
Die Reflektionslinien können wir über den Isolinien-Algorithmus
zeichnen, indem wir in Abhängigkeit von
als Funktionswert
verwenden. Auch wenn es kein realistisches Reflektionsmodell ist, kann
man über diese Reflektionslinien sehr schön kleine Unebenheiten,
etc. in der Fläche erkennen. Wichtig ist allerdings dabei eine
sinnvolle Wahl der Ebene und des Beobachtungspunktes. Es genügt auch
meistens nicht, die Fläche nur mit einer Einstellung zu untersuchen.
Abbildung 2.22 zeigt die Reflektionslinien für ein Fläche, deren Kontrollpunkte über das hyperbolische Paraboloid
![]() ![]() |
(2.85) |
Abbildung 2.23 zeigt die Reflektionslinien für
Irregularitäten der Ordnung ,
und
. Die Irregularitäten
liegen alle um den Punkt
und
die Reflektionsebene ist durch den Punkt
, den Lichtquellenrichtungsvektor
und den Abstandsvektor
gegeben. Für die
Irregularitäten der Ordnung
und
wurde resolution auf
, maxlevel auf
undmaxlines auf
gesetzt.
Für die Irregularität der Ordnung
war
resolution
,
maxlevel
und
maxlines
.
Für die in Abbildung 1.21 vorgestellte Acht zeigt
Abbildung 2.24 die Reflektionslinien für
eine zur -
-Ebene parallelen Ebene über der Acht. Aufgrund der
Irregularitäten sind diese sehr unregelmäßig. Auch ist es notwendig
maxlines und maxlevel des Isolinien-Algorithmus'
stark zu beschränken, um unnötigen Rechenaufwand am Rand des
Reflektionsgebietes zu vermeiden. maxlevel wurde für diese
Abbildung auf
, maxlines auf 6 und resolution
auf
gesetzt.