Der Hobby-Algorithmus
von Philipp Stephani
Einführung
In der zweidimensionalen Computergrafik stehen wir häufig vor dem Problem, durch eine gegebene Anzahl von Punkten eine glatte Kurve zu legen. Meist werden hierfür Splines verwendet. Dabei handelt es sich um miteinander verbundene Kurvenstücke. Besonders beliebt sind kubische Bézierkurven, da sie durch vier Kontrollpunkte mit einfacher geometrischer Bedeutung definiert sind und mit Hilfe des de-Casteljau-Algorithmus effizient und numerisch stabil berechnet werden können. In Abbildung 1 sehen wir zwei verbundene Bézierkurven, die beispielsweise Teil eines Béziersplines sein könnten. Die Bézierkurve auf der rechten Seite schneidet die beiden Knotenpunkte und . Die Tangenten an den Schnittpunkten schneiden die zugehörigen Kontrollpunkte und . Der Abstand von und von bzw. gibt grob gesprochen an, wie sehr sich die Kurve an die Tangenten anschmiegt.
Manchmal wollen wir Béziersplines durch eine Anzahl Knotenpunkte zeichnen, ohne die anderen Kontrollpunkte explizit gegeben zu haben. Vielmehr soll das resultierende Spline die Knotenpunkte so natürlich wie möglich, d. h. mit möglichst geringer Gesamtkrümmung, interpolieren. Dies mathematisch zu quantifizieren, ist ziemlich kompliziert. Ich möchte hier lediglich als Ergebnis den Hobby-Algorithmus vorstellen. Dieser wurde von dem amerikanischen Mathematiker John D. Hobby im Jahre 1985 entwickelt und von Donald E. Knuth für sein Schriftdefinitionssystem METAFONT, welches in TeX und LaTeX benutzt wird, eingesetzt. Verwendung findet der Algorithmus ebenfalls in den auf METAFONT basierenden Vektorgrafiksprachen METAPOST und Asymptote.
Definitionen
Sei mit . Gegeben seien Knotenpunkte , durch die wir ein kubisches Bézierspline mit durch den Hobby-Algorithmus ermittelten Kontrollpunkten legen wollen. Zur notationellen Vereinfachung definieren wir:
Dabei bezeichnen die Transposition des Vektors (sodass die Spaltenvektoren im sind) und die übliche euklidische Norm.
Grundsätzlich lassen sich zwei Typen von Splines unterscheiden: offene und geschlossene. Geschlossene Splines zeichnen sich gegenüber offenen dadurch aus, dass der letzte Punkt durch ein weiteres Kurvenstück wieder mit dem ersten Punkt verbunden ist. Geschlossene Splines heißen auch zyklisch. Bezüglich des Hobby-Algorithmus unterscheiden sich offene und geschlossene Splines in einigen wichtigen Details. Das Verhalten an den inneren Knotenpunkten ist jedoch genau gleich, sodass wir zunächst diese Punkte betrachten und erst später zwischen den beiden Splinetypen differenzieren.
Die inneren Knotenpunkte
Zunächst führen wir für jeden inneren Knotenpunkt die in Abbildung 1 eingezeichneten Winkel ein. ist der Winkel zwischen der Verbindungsstrecke zwischen und sowie der Verbindungsstrecke zwischen und , d. h. zwischen den Vektoren und . Die Winkel werden dabei so gewählt, dass gilt. ist der Winkel zwischen und der Verbindungsstrecke von und . Schließlich ist der Winkel zwischen der Verbindungsstrecke von und und der Verbindungsstrecke von und . Zu beachten ist, dass auf diese Weise auch und , nicht aber , , und definiert werden können.
Damit der Spline bei stetig differenzierbar ist, müssen , und auf einer Geraden liegen, und zwar derart, dass zwischen und liegt. Daraus folgt die Bedingung, dass , und sich zum Vollwinkel bzw. Nullwinkel ergänzen. Diese Bedingung werden wir später benötigen.
Durch die Winkel und ist zwar die Richtung der Kontrollpunkte und bezüglich gegeben, nicht aber ihr Abstand von . Wir benötigen also pro innerem Knotenpunkt noch zwei weitere Parameter. Diese sollen mit der lokalen Spannungsenergie des Splines an den Kontrollpunkten in Verbindung stehen und werden deshalb Spannungsparameter genannt. soll hierbei den Spannungsparameter des bei auslaufenden Kurvensegments bezeichnen, entsprechend den des einlaufenden Segments. Im Hobby-Algorithmus werden die Spannungsparameter so definiert, dass sich minimale Gesamtspannungsenergie (und damit natürlichstes Aussehen) für ergibt.
Zunächst betrachten wir lediglich eine einzelne Bézierkurve zwischen den Punkten und . Wir können das Problem vereinfachen, indem wir ausnutzen, dass bei einer gegebenen affinen Transformation diejenige Bézierkurve, die durch die mit transformierten Kontrollpunkte definiert ist, identisch mit der durch transformierten Bézierkurve ist. Mathematisch formuliert bedeutet dies, dass für die Bézierkurve mit den Kontrollpunkten , , und gilt:
Daraus folgern wir, dass wir eine Bézierkurve mit den Knotenpunkten und betrachten und die ermittelten Kontrollpunkte mit der affinen winkeltreuen Transformation , die auf und auf abbildet, transformieren können. ist eindeutig bestimmt durch
Für die zwei untransformierten Kontrollpunkte und gilt dann:
Dabei sind der Abstand zwischen und sowie der Abstand zwischen und . Hat man und erst einmal gefunden, ergeben sich die gesuchten Kontrollpunkte und einfach durch Anwendung von :
Die eigentliche Schwierigkeit am Hobby-Algorithmus ist die Ermittlung von , , und . Hobby entwickelt in seiner Publikation zunächst eine Methode, um und aus den Winkeln zu berechnen. Es gilt:
Entscheidend für die Qualität des Ergebnisses ist die Auswahl der Funktionen und .
Hobby wählt:
mit
Hierbei sind , und experimentell zu ermittelnde Konstanten; METAFONT und Asymptote wählen:
Damit ist das Problem zumindest für die inneren Knotenpunkte bis auf die Bestimmung der Winkel und gelöst. Für letzteres führt Hobby eine Krümmungsfunktion k ein:
Diese Funktion ist jedoch nichtlinear in den Variablen und , was auf ein schwierig zu lösendes nichtlineares Gleichungssystem für und hinausliefe. Um dies zu umgehen, wird nach entwickelt und nur der lineare Term benutzt. Man erhält unter Benutzung der linearen Näherungen und :
,
,
,
.
Diese Linearisierung führt dazu, dass die Interpolation bei sehr großen Winkeln , nicht mehr optimal ist. Derartig große Winkel kommen jedoch in der Praxis relativ selten vor, sodass die linearisierte Krümmungsfunktion für unsere Zwecke eine mehr als ausreichende Näherung darstellt.
Damit die Krümmung an den Knotenpunkten übereinstimmt, muss
gelten. Aus der Stetigkeit der linearisierten Krümmungsfunktion ergibt sich wiederum:
Mit den Abkürzungen
,
,
,
vereinfacht sich die letzte Gleichung zu:
Weiterhin gilt, wie oben erwähnt, aufgrund der stetigen Differenzierbarkeit an den Knotenpunkten:
Dies alles gilt natürlich nur an den inneren Knotenpunkten. Wir haben aus der Stetigkeit der Krümmungsfunktion und aus der stetigen Differenzierbarkeit des Splines ebenfalls , insgesamt also Bedingungen erhalten. Für die Kurvensegmente benötigen wir je zwei zusätzliche Kontrollpunkte. Die Abstände und der Kontrollpunkte von den Knotenpunkten lässt sich wie oben gezeigt aus den Winkeln und berechnen, somit benötigen wir pro Kontrollpunkt nur eine Gleichung (für den jeweils anliegenden Winkel). Dennoch fehlen immer noch zwei Bedingungen, für die wir die äußeren Knotenpunkte und betrachten und erstmals zwischen offenen und geschlossenen Splines unterscheiden müssen.
Offene Splines
Hier müssen wir zwei weitere Gleichungen künstlich einführen, da wir keine periodischen Randbedingungen haben. Analog zu den Spannungsparametern definiert Hobby die Wirbelparameter und derart, dass sich für ein natürliches Aussehen ergibt. Die Wirbelparameter beeinflussen das Aussehen des Splines an den Endpunkten. Für gibt es darüberhinaus einen weiteren Ausgangsspannungsparameter ; analog existiert für ein Eingangsspannungsparameter . Man wählt die folgenden Randbedingungen:
,
.
mit
,
.
Damit lassen sich und aus den anderen Gleichungen eliminieren:
,
.
Für lässt sich ebenfalls durch ersetzen:
Weiterhin gilt für :
.
Definiert man nun
,
,
,
,
,
,
,
so gilt:
,
,
.
Dies ist ein ein lineares tridiagonales Gleichungssystem der Form
mit Subdiagonale , Diagonale , Superdiagonale und rechtsseitigem Vektor , welches mit dem Gaußalgorithmus in linearer Zeit gelöst werden kann.
Sind alle und größer als , so gilt wegen , , und an den inneren Knotenpunkten:
.
An den Randpunkten folgt analog, falls zusätzlich und gelten:
,
.
Somit ist die Systemmatrix diagonaldominant. Das führt dazu, dass in diesem (in der Realität meistens angenommenen) Fall keine Pivotisierung nötig ist.
Geschlossene Splines
Hier haben wir periodische Randbedingungen vorliegen, weshalb es sich anbietet, die Indizes zyklisch zu definieren:
,
,
,
,
,
,
,
,
,
.
Weiterhin definieren wir und als den Winkel zwischen und sowie als den Winkel zwischen und . Damit können wir die Gleichungen Kruemmung und Differenzierbarkeit auch für und anwenden. Mit den Definitionen
,
,
,
erhalten wir wieder
Für und gelten mit obigen Definitionen die Spezialfälle:
,
.
Aufgrund der Periodizität des Problems ist die Gleichung für identisch zu der Gleichung für . Damit haben wir also für die Winkel (ein Winkel pro Knotenpunkt) Gleichungen gefunden, die nun aber kein einfaches tridiagonales Gleichungssystem mehr, sondern ein zyklisches tridiagonales Gleichungssystem der Form
bilden. Unter Zuhilfenahme der Sherman-Morrison-Formel kann auch dieses System mit linearer Zeitkomplexität gelöst werden.
Quellen
- John D. Hobby: Smooth, Easy to Compute Interpolating Splines, 1985
ftp://db.stanford.edu/pub/cstr/reports/cs/tr/85/1047/ - Martin Kerscher, Joachim Puls, Sigmung Stintzing: Numerik für Physiker, 2007
http://www.mathematik.uni-muenchen.de/~kerscher/vorlesungen/numeriksose08/doc/script.pdf - William H. Press, Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery:
Numerical Recipes in C++, Second Edition, Cambridge University Press
Ihre Meinung
Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.