Im vorherigen Kapitel wurde eine allgemeine Beschreibung der Klassen gegeben. Im Folgenden soll der Ablauf des Programms innerhalb der Klassen, wenn ein Polygon oder Polygonzug approximiert wird, am Beispiel eines nicht konvexen Polygons, das durch eine kubische Bézierkurve approximiert werden soll, erläutert werden.
Die Punkte des Polygons müssen zunächst in Instanzen der entsprechenden Klasse Punkt
33 gespeichert werden. Diese sollen dann in einer Instanz der Klasse Vector
34, in der vorgegebenen Reihenfolge vorliegen. Um dieses Polygon zu approximieren, wird die Methode poly2Kurve()
35 aufgerufen. Diese Methode benötigt das Vector
36 Objekt37, in dem die Punkte gespeichert sind, drei Gleitkommazahlen, sowie einen Booleschen Wert, der angibt, ob es sich um einen Polygonzug oder ein Polygon handelt. Die ersten beiden Gleitkommazahlen geben die Stellen der Bézierkurve an, an denen die Abstände zur Kante gemessen werden sollen, die für die Optimierung benötigt werden. In den Gleichungen wurden die Werte
und
genannt. Die dritte Gleitkommazahl gibt an, wie nahe sich die mittleren Kontrollpunkte an den äußeren Kontrollpunkten befinden. In den Gleichungen wurde dieser Wert
genannt.
In dieser Methode wird nun geprüft, welche Punkte in dem übergebenen Vector
für die Approximation überflüssig sind. Alle Eckpunkte, deren Winkel und deren zugehörige Kanten einen bestimmten Faktor unterschreiten, werden bei der Approximation nicht berücksichtigt. Dazu wird mithilfe der Methode canDelete()
38 geprüft, ob ein Eckpunkt berücksichtigt werden muss. Dazu werden lediglich der Eckpunkt, sowie die beiden Nachbarpunkte benötigt.
Anschließend wird das Polygon in seine konvexen Polygonzüge zerlegt. Dies geschieht mithilfe der Methode split2Segments()
39. Dafür wird das Vector
Objekt, sowie die Information, ob es sich um ein Polygon oder Polygonzug handelt, benötigt. Diese Information ist bedeutsam, weil Polygone an der zusätzlichen Kante, welche den ersten und den letzten Punkt verbindet, ebenfalls geteilt werden können.
Ein Richtungswechsel wird daran erkannt, dass der Rückgabewert der Methode getRichtung()
40, welche von der vorherigen Methode aufgerufen wird, das Vorzeichen ändert. Um die Richtung zu bestimmen, wird von der Methode lediglich ein Eckpunkt und die beiden benachbarten Eckpunkte benötigt. Die Richtung wird nach der Gleichung auf Seite 2.5 bestimmt.
An die Methode segment2Kurve()
41 werden dann die konvexen Polygonzüge einzeln übergeben, welche die Kontrollpunkte der berechneten Bézierkurve zurückgibt. Durch diese Methode wird zu Beginn geprüft, ob die Punkte im Uhrzeigersinn verlaufen, also einer Rechtskurve folgen. Falls dies nicht der Fall sein sollte, wird die Reihenfolge umgekehrt, um eine Rechtskurve zu erzeugen. Der Sonderfall, dass es sich um einen Polygonzug mit weniger als 4 Eckpunkten handelt, wird abgefangen und gesondert bearbeitet. Die übrigen Fälle werden wie vorher theoretisch erläutert optimiert.
Dazu wird ein Gleichungssystem erzeugt und für jede Kante die entsprechende Gleichung eingetragen. Die einzelnen Einträge in der Matrix werden mithilfe der Klasse BezierFormeln
42 berechnet. Dazu werden lediglich die Werte
und
sowie die vier Eckpunkte, welche die zur Gleichung gehörige Kante und die beiden Nachbarkanten definieren, benötigt. Die Klasse
BezierFormeln
43 berechnet die Einträge mit Hilfe der Klasse Converter
44, welche die Formeln verarbeitet. Die zwei Parameter
und
, die für die korrekte Approximation der Endkanten sorgen, entfallen, da sie den Wert Null haben.
Um den Punkt im Polyeder zu berechnen, welcher die optimale Bézierkurve wiedergibt, wird bei der Instanz des erzeugten Gleichungssystems die Methode findMinAlgo()
45 aufgerufen. Diese Methode gibt dann den Punkt des Polyeders zurück, der die Parameter enthält, welche die optimale Bézierkurve wiedergeben.
Diese Methode formt das Gleichungssystem wie in Kapitel 3.1.3 beschrieben solange um, bis es den optimalen Punkt im Polyeder gefunden hat. Wenn der optimale Punkt im Polyeder gefunden wurde, wird dieser in Form eines Arrays zurückgegeben.
In der Methode segment2Kurve()
46 wird aus den Parametern, die in dem Array vorliegen, die Bézierkurve berechnet. Das geschieht ebenfalls unter Zuhilfenahme der Klasse BezierFormeln
47, welche die Formeln zur Berechnung der Kontrollpunkte aus den Parameter enthält.
Nachdem alle konvexen Teilstücke approximiert wurden, werden diese mit Hilfe der Methode unionSegments()
48 wieder zusammengefügt. Die entstandene Bézierkurve kann nun einfach in einem vektorgraphischen Format gespeichert werden.
Karl kleine Kruse 2007-09-16