Seminar Konvexe Hülle einer Punktmenge Jan Barth, 49109 Nadja Casper, 53496 Marcus Ganske, 36603 Betreuer: Prof. Dr. habil. Thomas Thierauf 25. Januar 2017 Inhaltsverzeichnis 1 Grundlagen 1.1 Kreuzprodukt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Richtung von Winkeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 5 2 Definitionen 2.1 Konvexe Menge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Konvexe Polygone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Konvexe Hülle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 7 8 3 Algorithmen 3.1 Graham’s Scan . . . . . . . . 3.1.1 Pseudocode . . . . . . 3.1.2 Korrektheitsbeweis . . 3.1.3 Laufzeit, Speicher etc. 3.2 weitere Algorithmen . . . . . . . . . . 8 9 10 14 15 17 4 Konvexe Hülle mit mehr als zwei Dimensionen 4.1 Allgemein . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Pseudocode für dreidimensionalen Raum . . . . . . . . . . . . . . . . . . . . 18 18 19 5 Anwendung 5.1 Als Basis für andere Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Computergrafiken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 20 21 . . . . . . . . . . . . . . . . . . . . 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Grundlagen 1.1 Kreuzprodukt Die Berechnung des Kreuzprodukts zweier Vektoren ist eine grundlegende Operation in der algorithmischen Geometrie. Das Ergebnis eines Kreuzprodukts ist ein dritter Vektor. Dessen Betrag entspricht dem Flächeninhalt des Parallelogramms, welches von den Punkten (0|0), p1 , p2 und p1 + p2 eingeschlossen wird.[3] Abbildung 1: Kreuzprodukt zweier Vektoren ist die Fäche, die zwischen den Punkten (0|0), p1 , p2 und der Summe der beiden. Um das Kreuzprodukt der Vektoren p#‰1 und p#‰2 zu berechnen, kann folgende Gleichung verwendet werden: p1 × p2 = (x1 ∗ y2 ) − (x2 ∗ y1 ) (1) Gleichung (1) entnommen aus [3] Beim Ergebnis des Kreuzprodukts kann zwischen drei Fällen unterschieden werden. 1. p#‰1 × p#‰2 > 0 Wenn das Ergebnis des Kreuzprodukts der Vektoren p#‰1 und p#‰2 größer 0 ist, befindet sich Vektor p#‰1 im Uhrzeigersinn gedreht von Vektor p#‰2 aus gesehen. 2. p#‰1 × p#‰2 < 0 Wenn das Ergebnis des Kreuzprodukts der Vektoren p#‰1 und p#‰2 kleiner 0 ist, befindet sich Vektor p#‰1 entgegen dem Uhrzeigersinn von Vektor p2 aus gesehen. 3. p#‰1 × p#‰2 = 0 Ist das Ergebnis des Kreuzproduktes der Vektoren p#‰1 und p#‰2 gleich 0, zeigen die beiden Vektoren entweder in die selbe, oder in die entgegengesetzte Richtung. 2 [3] Abbildung 2: Je nach Ergebnis des Kreuzprodukts zweier Vektoren, liegen die beiden Vektoren zueinander. Hier sieht man die unterschiedlichen Bereiche. In Abbildung 2 sieht man einen Vektor #‰ p. #‰ #‰ Ist das Kreuzprodukt des Vektors #‰ p mit einem beliebigen Vektor p0 ( #‰ p × p0 ) der seinen #‰ Ursprung in (0|0) hat größer als 0, so befindet sich der Vektor p0 im dunkelgrauen Bereich. #‰ Ist das Kreuzprodukt kleiner als 0, befindet sich der Vektor p0 im hellgrauen Bereich. #‰ Ist das Kreuzprodukt gleich 0, so befindet sich Vektor p0 genau zwischen den beiden grauen Flächen auf der gelben Gerade. In diesem Fall kann jedoch nicht am Vorzeichen des Kreuz#‰ produkts entschieden werden, ob p0 in die gleiche oder in die entgegengesetzte Richtung von #‰ p zeigt.[3] Beispiel 1: Abbildung 3: Kreuzprodukt der Vektoren p#‰1 , p#‰2 ist > 0 3 ! ! 5 4 p#‰1 = p#‰2 = 2 6 p#‰1 × p#‰2 = x1 y2 − x2 y1 =5∗6−4∗2 = 30 − 8 = 22 > 0 Das Kreuzprodukt ist größer als 0, damit befindet sich Vektor p#‰1 im Uhrzeigersinn gedreht von Vektor p#‰2 aus. Das Ergebnis wird durch die Abbildung bestätigt. Beispiel 2: Abbildung 4: Kreuzprodukt der Vektoren p#‰1 , p#‰2 ist < 0 ! ! 4 7 p#‰1 = p#‰2 = 3 −2 p#‰1 × p#‰2 = x1 y2 − x2 y1 = 4 ∗ (−2) − 7 ∗ 3 = −8 − 21 = −29 < 0 Das Kreuzprodukt ist kleiner als 0, damit befindet sich Vektor p#‰1 entgegen dem Uhrzeigersinn gedreht von Vektor p#‰2 aus. Das Ergebnis wird durch die Abbildung bestätigt. 4 Beispiel 3: #‰ Abbildung 5: Das Kreuzprodukt der Vektoren p1, p#‰2 ist < 0 ! ! −2 4 p#‰2 = p#‰1 = −1 2 p#‰1 × p#‰2 = x1 y2 − x2 y1 = 4 ∗ (−1) − (−2) ∗ 2 = −4 − (−4) =0 Das Kreuzprodukt ist gleich 0, damit zeigen die Vektoren p#‰1 und p#‰2 in die selbe oder entgegengesetzte Richtung. Das Ergebnis wird durch die Abbildung bestätigt. 1.2 Richtung von Winkeln Für manche Algorithmen zur Berechnung der konvexen Hülle benötigt man eine Methode um herauszufinden, ob ein Winkel der von zwei Strecken gebildet wird, eine Links oder eine Rechtkurve darstellt. Im Unterschied zum bisher Gezeigten, ist es hier nicht zwingend notwendig, dass die Vektoren ihren Ursprung in (0|0) haben. Sie können beliebig im (zweidimensionalen) Raum stehen. Gegeben seien zwei Vektoren p# 0 p‰1 und p# 1 p‰2 . Es soll nun herausgefunden werden, in welche Richtung die Kurve um den Winkel ∠p0 p1 p2 verläuft. Um das zu tun, kann das Kreuzprodukt verwendet werden. Dabei wird zwar nicht die genaue Größe des Winkels berechnet, es wird aber eindeutig bestimmt, was für eine Kurve der Winkel bildet. Es wird ein Hilfsvektor p# 0 p‰2 konstruiert. Äquivalent zu der Richtung der Kurve am Winkel ∠p0 p1 p2 ist nun die Frage, ob der Hilfsvektor p# 0 p‰2 vom Vektor p# 0 p‰1 aus gesehen im oder entgegen dem Uhrzeigersinn liegt. 5 Das kann mit der Gleichung (p2 − p0 ) × (p1 − p0 ) = (x2 − x0 )(y1 − y0 ) − (x1 − x0 )(y2 − y0 ) = n (2) Gleichung (2) entnommen aus [3] bestimmt werden. Für ein positives n größer 0 gilt: Der Hilfsvektor p# 0 p‰2 ist im Uhrzeigersinn von p# 0 p‰1 aus gesehen. Damit stellen die Vektoren, die den Winkel ∠p0 p1 p2 bilden. eine Rechtskurve dar. Für ein negatives n kleiner 0 gilt: Der Hilfsvektor p# 0 p‰2 ist entgegen dem Uhrzeigersinn von p# 0 p‰1 aus gesehen. Damit stellen die Vektoren, die den Winkel ∠p0 p1 p2 bilden, eine Linkskurve dar. Für n = 0 gilt: Die Punkte p0 , p1 , p2 sind kollinear (d.h. sie liegen auf einer Geraden). [3] Beispiel: Abbildung 6: Die Vektoren p# 0 p‰1 und p# 1 p‰2 können eine Links oder eine Rechtskurve darstellen. p0 = (5|2) p1 = (8|4) p2 = (6|5) (p#‰2 − p#‰0 ) × (p#‰1 − p#‰0 ) = (x2 − x0 )(y1 − y0 ) − (x1 − x0 )(y2 − y0 ) = (6 − 5)(4 − 2) − (8 − 5)(5 − 2) =1∗2−3∗3 =2−9 = −7 < 0 Das Ergebnis ist kleiner als 0. Die Vektoren p# 0 p‰1 und p# 1 p‰2 bilden also eine Linkskurve. 6 2 Definitionen 2.1 Konvexe Menge Eine Teilmenge ist genau dann konvex, wenn für zwei beliebige Punkte, die zu dieser Menge gehören, auch deren Verbindungsstrecke komplett innerhalb dieser Menge liegt. Das heißt, es gibt keine konkaven Ausbuchtungen. [6] Abbildung 7: Konvexe Menge Abbildung 8: Nichtkonvexe Menge Das heißt, für die Punkte a, b ∈ S gilt: ab ∈ S Beispiele konvexer Mengen sind die leere Menge, alle einelementigen Mengen, Strecken und Geraden, einfache, regelmäßige Polygonflächen, sowie Kreise. 2.2 Konvexe Polygone Polygone werden unterschieden in konvexe und konkave, beziehungsweise sternförmige Polygone. Ein konvexes Polygon ist ein Spezialfall einer allgemeinen konvexen Menge von Punkten. Bei diesen ist jeder Eckpunkt von jedem anderen Eckpunkt aus „sichtbar“. Das heißt, dass Verbindungsstrecken - in den Abbildungen die gestrichelten Linien - zu jedem anderen Eckpunkt gemacht werden können, ohne dabei an die Kanten des Polygons zu stoßen. Bei sternförmigen Polygonen ist dies nicht der Fall. Die gedachte Gerade zwischen den Punkten schneidet die äußeren Kanten. [4] Als Beispiele für konvexe Polygone können alle einfachen regelmäßigen Polygone, diese sind sowohl gleichseitig, als auch gleichwinklig, genannt werden. Dies sind u. A. gleichseitige Dreiecke, Quadrate, Fünfecke usw. 7 Abbildung 10: Sternförmiges Polygon Abbildung 9: Konvexes Polygon 2.3 Konvexe Hülle Die konvexe Hülle einer Punktmenge Q ist nun also das kleinste konvexe Polygon P , für das jeder Punkt in Q entweder auf den Außenkanten oder im Inneren des Polygons P liegt. [5] Hierbei wird angenommen, dass jeder Punkt in Q nur ein Mal vorkommt und dass Q mindestens drei Punkte beinhaltet, die nicht kollinear, d. h. sie liegen nicht auf einer Gerade, sind. Anders ausgedrückt ist die konvexe Hülle der kürzeste Pfad, der alle Punkt in Q umschließt. Veranschaulicht werden kann dies durch das folgende, in der Fachliteratur immer wieder auftretende Beispiel. Die Punkte in Q sind Nägel, die auf ein Brett geschlagen werden. Anschließend wird ein Gummiband um die Nägel gespannt und losgelassen. Die Punkte, die das Gummiband umschließt, sind die Punkte, die die konvexe Hülle beschreiben. [3] Abbildung 11: Konvexe Hülle Die äußere schwarze Linie ist das Gummiband, das, wenn es losgelassen wird, zur blauen Linie wird, die die konvexe Hülle dieser Punktmenge darstellt. 3 Algorithmen In diesem Abschnitt werden zwei Algorithmen vorgestellt, die die konvexe Hülle einer Menge mit n Punkten berechnen: Graham’s scan und Jarvis’ march. Beide Algorithmen geben die 8 konvexe Hülle linksdrehend, also gegen den Uhrzeigersinn, aus. Wie Abbildung 5 zeigt, ist jeder Knoten CH(Q) ein Punkt in Q. Beide Algorithmen nutzen diese Eigenschaft aus, um zu entscheiden, welche Knoten von Q in die konvexe Hülle einbezogen und welche verworfen werden. Die komplexe Hülle kann mit einem Zeitaufwand von O(n log n) mittels verschiedener Methoden berechnet werden. Sowohl Graham’s scan als auch Jarvis’ march verarbeiten die Knoten in der Reihenfolge ihrer Polarwinkel mit einem Referenzknoten. Abbildung 12: Eine Menge von Punkten Q = {p0 , p1 . . . p12 } mit ihrer konvexen Hülle CH(Q) in grau. Quelle: [3] Andere Methoden werden hier nur erwähnt. Für weitere Informationen sei auf die Literatur [3] verwiesen. • die inkrementelle Methode • die divide-and-conquer Methode • die prune-and-search Methode Die Berechnung einer konvexen Hülle einer Punktmenge ist für sich schon ein interessantes Problem. Außerdem beginnen einige Algorithmen für Probleme der algorithmischen Geometrie damit, die konvexe Hülle zu berechnen. Man bedenke zum Beispiel das zweidimensionale farthest pair problem: Es wird eine Menge von n Punkten in einer Ebene vorgegeben. Nun sollen die beiden Punkte ermittelt werden, die voneinander den grös̈ten Abstand haben. Diese Punkte müssen Knoten der konvexen Hülle sein. Das farthest pair eines n-Knoten-Polygons kann mit einem Zeitaufwand von O(n) berechnet werden. Indem man zuerst die konvexe Hülle der n Punkte in O(n log n) berechnet und danach das farthest pair im resultierenden konvexen Polygon findet, kann das farthest pair einer beliebigen Punktmenge mit n Punkten in O(n log n) gefunden werden. 3.1 Graham’s Scan Graham’s scan löst das Problem der konvexen Hülle, indem ein Stack S mit möglichen Punkten angelegt wird. Er legt alle Punkte in Q einmal auf den Stack und entfernt letztendlich 9 die Punkte, die kein Knoten in CH(Q) sind, wieder. Wenn der Algorithmus terminiert, sind auf S nur noch die Knoten von CH(Q), gegen den Uhrzeigersinn in der Reihenfolge ihres Auftretens in der Umgrenzung geordnet. Die Prozedur Graham-Scan erhält als Eingabe eine Menge Q an Punkten, wobei |Q| ≥ 3. Sie ruft die Funktionen Top(S), die das oberste Element des Stacks S zurück gibt und Next-To-Top(S), die das Element unter dem obersten Element des Stacks S zurück gibt, auf. Beide Funktionen verändern den Stack nicht. Wie gleich bewiesen wird, enthält der Stack, den Graham-Scan zurückgibt, genau die Knoten von CH(Q) gegen den Uhrzeigersinn geordnet. 3.1.1 Pseudocode Graham-Scan[3] Eingabe: Punktmenge Q Ausgabe: konvexe Hülle von P 1. Sei p0 der Punkt in Q mit der geringsten y-Koordinate oder der am Weitesten links gelegene bei mehreren solchen 2. Seien hp1 , p2 , . . . , pm i die verbliebenen Punkte in Q, sortiert gegen den Uhrzeigersinn nach Polarwinkel(wenn mehrere Punkte kollinear sind, nehme nur denjenigen, der am Weitesten von p0 entfernt ist) 3. Sei S ein leerer Stack 4. Push(p0 , S) 5. Push(p1 , S) 6. Push(p2 , S) 7. for i = 3 to m 8. while der Winkel zwischen den Punkten Next-To-Top(S), Top(S) und pi dreht sich nicht nach links 9. 10. Pop(S) Push(pi , S) 11. return S Abbildung 12 veranschaulicht den Fortschritt von Graham-Scan. Zeile 1 wählt als p0 den Punkt mit der niedrigsten y-Koordinate und denjenigen, der am Weitesten links ist, falls es mehrere mit der niedrigsten y-Koordinate gibt. Da es in Q keine Punkte gibt, die unter p0 sind und alle auf gleicher Höhe rechts von p0 liegen, muss p0 ein Knoten in CH(Q) sein. Zeile 2 sotriert die restlichen Punkte in Q nach ihrem Polarwinkel zu p0 , indem die Kreuzprodukte verglichen werden. Haben mehrere Punkte den selben Polarwinkel zu p0 , sind alle außer dem weitesten Linearkombinationen aus diesem und p0 , deshalb werden sie entfernt. m zeigt die Anzahl der übrigen Punkte an, außer p0 . Der Polarwinkel, gemessen im Bogenmaß, jedes Punktes im Verhältnis zu Q liegt im offenen Intervall [0, π).Da die Punkte 10 nach aufsteigendem Polarwinkel geordnet sind, sind sie gegen den Uhrzeigersinn in Bezug auf p0 geordnet. Diese geordnete Sequenz von Punkten wird mit hp1 , p2 , . . . , pm i bezeichnet. Man beachte, dass die Punkte p1 und pm Knoten von CH(Q) sind. Abbildung 13 (a) zeigt die Punkte aus Abbildung 6 der Reihe nach geordnet mit aufsteigendem Polarwinkel in Bezug auf p0 . Die restliche Prozedur benutzt den Stack S. Die Zeilen 3 - 6 initialisieren den Stack mit, von unten nach oben, den Punkten p0 , p1 und p2 . Abbildung 13(a) zeigt den anfänglichen Stack S. Die for-Schleife in den Zeilen 7 - 10 iteriert einmal für jeden Punkt der Untersequenz hp3 , p4 , . . . , pm i. Man sieht, dass der Stack S nach Bearbeitung des Punktes pi , von unten nach oben, die Knoten von CH({p0 , p1 , . . . , pi }) gegen den Uhrzeigersinn geordnet enthält. Die while-Schleife in den Zeilen 8 und 9 entfernt Punkte aus dem Stack, wenn sie nicht Teil der konvexen Hülle sind. Wenn die konvexe Hülle gegen den Uhrzeigersinn durchlaufen wird, sollte an jedem Knoten eine Drehung nach links vollzogen werden. Findet die while-Schleife einen Knoten, an dem nicht nach links gedreht wird, entfernt sie den Knoten aus dem Stack.(Bei einer Überprüfung auf eine nicht linke Drehung wird im Vergleich zur Rechtsdrehung auch entdeckt, ob der Winkel gerade ist. Diese will man auch nicht, da kein Knoten eines konvexen Polygons eine Linearkombination zweier anderen Knoten des Polygons sein darf). Nachdem auf dem Weg zu pi alle Knoten, bei denen nicht nach links gedreht wird, aus dem Stack entfernt wurden, wird pi auf den Stack gelegt. Die Abbildungen 13(b)-(k) zeigen den Zustand des Stacks S nach jeder Iteration der forSchleife. Am Ende gibt Graham-Scan den Stack in Zeile 11 zurück. Abbildung 13(l) zeigt die entsprechende konvexe Hülle.[3] 11 (a) (b) (c) (d) (e) (f) Abbildung 13: Die Ausführung von Graham-Scan auf der Menge Q aus Abbildung [x]. Die momentane konvexe Hülle in S ist für jeden Schritt in grau gehalten. (a) die Sequenz hp1 , p2 , . . . , p12 i von Punkten nach aufsteigendem Polarwinkel in Bezug auf p0 durchnummeriert. (b)-(k) Stack S nach jeder Iteration der for-Schleife in den Zeilen 7 - 10. Gestrichelte Linien zeigen Drehungen, die nicht nach links gehen.Dies führt dazu, dass die Punkte aus dem Stack entfernt werden. In Teilbild (h) beispielsweise führt der Winkel anglep7 p8 p9 dazu, dass p8 entfernt wird, und danach führt die Rechtsdrehung im Winkel angle p6 p7 p9 dazu, dass p7 entfernt wird. Quelle: [3] 12 (g) (h) (i) (j) (k) (l) Abbildung 14: (l) die konvexe Hülle, die von der Prozedur ausgegeben wird Quelle: [3] 13 3.1.2 Korrektheitsbeweis Wenn Graham-Scan auf einer Menge von Q Punkten mit |Q| ≥ 3 ausgeführt wird, enthält der Stack S von unten nach oben genau die Knoten von CH(Q) gegen den Uhrzeigersinn geordnet. Beweis. Nach Zeile 2 hat man die Sequenz von Punkten hp1 , p2 , . . . , pm i. Man definiert, für i = 2, 3, . . . , m, die Untermenge Q1 = {p0 , p1 , . . . , pi } Die Punkte Q − Qm sind diejenigen, die entfernt wurden, da sie den selben Polarwinkel in Bezug auf p0 wie ein Punkt in Qm hatten; diese Punkte sind nicht in CH(Q), somit ist CH(Qm ) = CH(Q). Damit genügt es zu zeigen, dass der Stack S von unten nach oben aus den Knoten von CH(Qm ) gegen den Uhrzeigersinn geordnet enthält, wenn Graham-Scan terminiert. Man beachte, dass genauso wie p0 , p1 und pm Knoten von CH(Q) sind, die Punkte p0 , p1 und pi allesamt Knoten von CH(Qi ) sind. Der Beweis nutzt die folgende Schleifeninvariante: Zu Beginn jeder Iteration der for-Schleife in den Zeilen 7 - 10 besteht der Stack S, von unten nach oben, genau den Knoten von CH(Qi−1 ) gegen den Uhrzeigersinn geordnet. Initialisierung: Die Invariante gilt beim ersten Erreichen der Zeile 7, da der Stack S zu dieser Zeit exakt aus den Kanten von Q2 = Qi−1 besteht und diese Menge aus drei Knoten ihre eigene konvexe Hülle bildet. Außerdem liegen sie gegen den Uhrzeigersinn geordnet von unten nach oben auf dem Stack. (a) (b) Abbildung 15: Korrektheitsbeweis von Graham-Scan. (a) Weil der Polarwinkel von pi in Bezug auf p0 größer ist als der von pj und weil der Winkel ∠pk pj pi eine Linksdrehung macht, erhält man durch Hinzufügen von pi zu CH(Qj ) genau die Kanten von CH(Qj ∪ {pi }). (b) Wenn der Winkel ∠pr pt pi keine Linksdrehung macht, ist pt entweder im Inneren eines Dreiecks aus p0 , pr und pi oder liegt auf einer Kante des Dreiecks, was bedeutet, dass er kein Knoten von CH(Q) sein kann. Quelle: [3] Erhaltung: Beim Betreten einer Iteration der for-Schleife ist der oberste Punkt des Stacks pi−1 , der am Ende der letzten Iteration dort abgelegt wurde (oder vor der ersten 14 Iteration, falls i = 3). Sei pj der oberste Punkt auf S nach Ausführung der while-Schleife in den Zeilen 8-9, aber bevor die Zeile 10 pi auf den Stack legt und sei pk der Punkt genau unter pj auf S. In dem Moment, in dem pj das oberste Element des Stacks ist und pi noch nicht drauf gelegt wurde, enthält der Stack die selben Punkte, die er nach der Iteration j der for-Schleife enthielt. Bei Erreichen der Schleifeninvariante enthält S deshalb genau die Knoten in CH(Qj ) von unten nach oben entgegen des Uhrzeigersinns geordnet. Man konzentriert sich nun auf den Moment just bevor pi auf den Stack gelegt wird. Es ist bekannt, dass der Polarwinkel von pi in Bezug auf p0 größer ist als der von pj und dass der Winkel ∠pk pj pi eine Linksdrehung vollzieht(ansonsten wäre pj entfernt worden). Deswegen, weil S im Moment genau die Knoten von CH(Qj ) enthält, sieht man in Abbildung 14(a), dass der Stack genau die Knoten von CH(Qj )∪{pi } in Ordnung entgegen des Uhrzeigersinns enthält, sobald pi auf dem Stack abgelegt wird. Nun wird gezeigt, dass CH(Qj ) die selbe Menge von Punkten ist wie CH/Qi ). Es wird ein beliebiger Punkt pt , der während der Iteration i der for-Schleife vom Stack entfernt wurde, betrachtet und angenommen pr sei der Punkt direkt unter pt in dem Moment, als pt entfernt wurde(pr könnte pj sein). Der Winkel ∠pr pt pi macht keine Linksdrehung und der Polarwinkel von pt in Bezug auf p0 ist größer als der von pr . Wie Abbildung 14(b) zeigt, muss pt entweder im Inneren eines Dreiecks, das von p0, pr und pi gebildet wird, liegen oder auf einer Kante (kann aber selbst kein Knoten des Dreiecks sein). Es ist deutlich, dass pt kein Knoten von CH(Qi ) sein kann, da er innerhalb des Dreiecks liegt, das von drei anderen Punkten von Qi gebildet wird. Da pt kein Knoten von CH(Qi ) ist, bekommt man CH(Qi − {pt }) = CH(Qi ) (3) Sei Pi die Menge von Punkten, die während der Iteration von i der for-Schleife vom Stack entfernt wurden. Da die Gleichung (2) für alle Punkte in Pi gilt, kann sie wiederholt angewandt werden, um zu zeigen, dass CH(Qi − Pi ) = CH(Qi ). Aber Qi − Pi = Qj ∪ {pi }, und so kann man darauf schließen, dass CH(Qj ∪ {pi }) = CH(Qi − Pi ) = CH(Qi ). Es wurde gezeigt, dass der Stack S genau die Knoten von CH(Qi ) in Reihenfolge gegen den Uhrzeigersinn von unten nach oben enthält, sobald pi auf den Stack gelegt wird. Die Inkrementierung von i bewirkt dann, dass die Schleifeninvariante für den nächsten Durchlauf gilt. Ende: Wenn die Schleife terminiert ist i = m + 1 und die Schleifeninvariante impliziert, dass der Stack S genau aus den Kanten CH(Qm ) besteht, was CH(Q) entspricht, von unten nach oben in der Reihenfolge gegen den Uhrzeigersinn geordnet. Dies beendet den Beweis. [3] 3.1.3 Laufzeit, Speicher etc. Im Folgenden soll gezeigt werden, dass die Laufzeit von Graham-Scan O(n log n) ist, wobei n = |Q|. Zeile 1 benötigt Θ(n log n) Zeit. Zeile 2 hat einen Zeitaufwand von O(n log n), wenn der Merge Sort oder Heapsort verwandt wird, um die Polarwinkel zu sortieren und die Kreuzproduktmethode aus Abschnitt 1.1, um Winkel zu vergleichen.(Alle außer der am Weitesten entfernte Punkt mit dem selben Polarwinkel können mit insgesamt O(n) Zeitaufwand aus allen Punkten n entfernt werden). Die Zeilen 3 - 6 haben einen Zeitaufwand von O(1). Da m ≤ n − 1, wird die for-Schleife in den Zeilen 7 - 10 maximal n − 3 mal durchlaufen. Da 15 Push in O(1) abgehandelt werden kann, ist der Zeitaufwand jeder Iteration O(1) plus der Zeit, die in der while-Schleife in den Zeilen 8-9 benötigt wird, und somit hat die for-Schleife einen gesamten Zeitaufwand von O(n) plus der Zeit in der geschachtelten while-Schleife. Um zu zeigen, dass die while-Schleife einen Zeitaufwand von O(n) hat, wird eine Gesamtanalyse verwandt. Für i = 0, 1, . . . , m wird jeder Punkt pi genau einmal auf den Stack gelegt. Mindestens drei Punkte - p0 , p1 und pm - werden nie vom Stack entfernt. Somit werden maximal m − 2 Pop-Operationen ausgeführt. Jede Iteration der while-Schleife führt ein Pop aus, also gibt es maximal m − 2 Iterationen durch die while-Schleife. Weil der Test in Zeile 8 eine Laufzeit von O(1) hat, benötigt jeder Aufruf von Pop auch O(1) Zeit, und da m ≤ n − 1, hat die while-Schleife insgesamt eine Laufzeit von O(n). Damit ist die Gesamtlaufzeit von Graham-Scan O(n log n) Da jeder Punkt der Menge genau einmal auf den Stack gelegt wird, hat Graham-Scan eine Speicherkomplexität von O(n).[3] 16 3.2 weitere Algorithmen Abbildung 16: Die Operation von Jarvis’ march. Als erster Punkt wird der niedrigste Punkte p0 gewählt. Der Punkt p1 hat den kleinsten Polarwinkel in Bezug auf p0 . Der nächste Punkt p2 hat den niedrigsten Polarwinkel in Bezug auf p1 . Die rechte Kette geht bis zum höchsten Punkt p3 . Dann wird die linke Kette analog konstruiert, jedoch mit Bezug auf die negative x-Achse. Quelle: [3] Jarvis’ March Jarvis’ march berechnet die konvexe Hülle einer Punktmenge Q mit einem Verfahren, das als gift wrapping bekannt ist. Der Algorithmus hat eine Laufzeit von O(nh), wobei h die Anzahl der Kanten in CH(Q) ist. Wenn h o(log n) ist, ist Jarvis’ march asymptotisch schneller als Graham’s scan. Intuitiv simuliert Jarvis’ march das Umwickeln der Menge Q mit einem straffen Papier. Man beginnt damit, das Papier an den niedrigsten Punkt der Menge zu „kleben “, d.h. an den selben Punkt p0 , mit dem Graham’s scan beginnt. Es ist bekannt, dass dieser Punkt ein Knoten der konvexen Hülle sein muss. Nun wird das Papier gespannt und nach oben gezogen, bis es einen Punkt berührt. Dieser Punkt muss auch Teil der konvexen Hülle sein. Während das Papier auf Spannung gehalten wird, wird so weiter verfahren, bis man wieder am Punkt p0 ankommt. Formaler ausgedrückt, erstellt Jarvis’ march eine Sequenz H = hp0 , p1 , . . . , ph−1 i der Knoten von CH(Q). Man beginnt mit p0 . Wie Abbildung 9 zeigt, hat der nächste Knoten p1 den kleinsten Polarwinkel in Bezug auf p0 (Im Fall eines Gleichstandes wird der Punkt gewählt, der am Weitesten von p0 entfertnt ist). Ebenso hat p2 den kleinsten Polarwinkel in Bezug auf p1 , und so weiter. Wird der höchste Punkt pk erreicht, hat man, wie Abbildung 9 zeigt, die rechte Kette von CH(Q) konstruiert. Um die linke Kette zu konstruieren, beginnt man bei pk und wählt pk+1 als Punkt mit dem kleinsten Polarwinkel auf pk bezogen, aber auf der negativen x-Achse. Dies führt man so fort, bis man wieder bei p0 ankommt. 17 Jarvis’ march könnte auch so implementiert werden, dass keine separaten Teilketten berechnet werden müssen. Diese Implementierungen merken sich üblicherweise den Winkel der letzten Seite der konvexen Hülle und erfordern, dass der Winkel sich stetig (im Bereich 0 bis 2π Bogenmaß) erhöht. Der Vorteil, verschiedene Ketten zu konstruieren, liegt darin, dass die Winkel nicht explizit berechnet werden müssen; das Verfahren in Abschnitt 1.1 reicht vollkommen aus, um Winkel zu vergleichen. Wenn er richtig implementiert wurde, hat Jarvis’ march eine Laufzeit von O(nh). Für jede der h Knoten in CH(Q) wird der Knoten mit dem kleinsten Polarwinkel gefunden. Jeder Vergleich zweier Winkel hat einen Aufwand von O(1) mit dem Verfahren aus Abschnitt 1.1. 4 Konvexe Hülle mit mehr als zwei Dimensionen 4.1 Allgemein Bisher wurde die konvexe Hülle für zweidimensionale Punktmengen beschrieben. Prinzipiell gibt es für alle n-dimensionalen Punktmengen eine konvexe Hülle. Hierbei ist die konvexe Hülle ein n-dimensionales Polytop. Da konvexe Polygone eine Teilmenge der konvexen Polytope sind, ist auch die Definition analog.[1] Ein Polytop ist konvex, wenn "die Verbindungsstrecke zwischen zwei beliebigen Punkten des Polytops"[8] komplett innerhalb des Polytops liegt. Abbildung 17: Konvexes Polytop Abbildung 16 siehe [8] 18 4.2 Pseudocode für dreidimensionalen Raum ConvexeHullThreeSpace(P) Eingabe: dreidimensionale Punktmenge P Ausgabe: konvexe Hülle von CH(P ) von P 1. Finde vier Punkte p1 , p2 , p3 , p4 in P, die einen Tetraeder formen 2. C ← CH({p1 , p2 , p3 , p4 }) 3. Berechne eine zufällige Permutation p5 , p6 , . . . , pn aus den übrigen Punkten 4. Initialisiere den Konfliktgraphen G mit allen sichtbaren Paare (pt , f ), bei denen f eine Seite von C und t > 4 ist. 5. for i ← 5 to n 6. 7. 8. do \\Füge pr in C ein: if Fconf lict (pr ) ist nicht leer \\der Fall, dass pr außerhalb von C liegt then Lösche alle Seiten in Fconf lict (pr ) aus C 9. Laufe die Grenze der sichtbaren Region von pr und erstelle eine Liste L mit den Horizont-Kanten for alle e ∈ L 10. 11. do Verbinde e mit pr indem eine dreieckige Fläche f erstellt wird if f ist koplanar mit der benachbarten Fläche f 0 an e 12. 13. then verschmelze die Flächen f und f 0 zu einer Fläche deren Konfliktliste der von f 0 entspricht. 14. else \\Bestimme die Konflikte in f : 15. Erstelle einen Knoten für f in G. 16. Seien f1 und f2 die Flächen in der alten konvexen Hülle einfallend zu e. 17. P (e) ← Pconf lict (f1 ) ∪ Pconf lict (f2 ) 18. for alle Punkte p ∈ P (e) do wenn f von p aus sichtbar ist, füge (p, f ) zu G hinzu 19. 20. Lösche den pr entsprechenden Knoten und die den Flächen in Fconf lict (pr ) entsprechenden Knoten zusammen mit ihren einfallenden Bögen aus G. 21. return C [1] 19 5 5.1 Anwendung Als Basis für andere Algorithmen Die konvexe Hülle kann dazu verwendet werden, andere grundlegende Algorithmen durchzuführen. Als Beispiel ist hier das Sortieren von Zahlen zu nennen, was im Folgenden gezeigt werden soll. Gegeben sei ein unsortiertes Array A mit den Elementen a1 , a2 , . . . , an . Bildet man nun jedes Element des Arrays mit an → (an |a2n ) ab, so erhält man Punkte, die auf der Normalparabel liegen. Berechnet man nun die konvexe Hüelle dieser Punkte mit einem geschickt gewählten Startpunkt, so ist die Ausgabe das sortierte Array. An dieser Stelle lässt sich eine weitere Aussage zum Laufzeitverhalten der Berechnung der konvexen Hüelle machen. Da ein Sortieralgorithmus minimal die Laufzeit Ω(n log n) hat, kann die Komplexität der Berechnung der konvexen Hülle nicht geringer sein. Andernfalls könnte man auch schneller sortieren, was nachweislich nicht geht.[5] Beispiel : Abbildung 18: Konvexe Hülle der Punktemenge {(xi , xi 2 )} Quelle: [5] In Abbildung 16 sieht man die Normalparabel, mit sechs markierten Punkten. Diese Punkte sind abgebildete Werte eines zu sortierenden Arrays. Die konvexe Hülle der Punktemenge ist bereits rot eingezeichnet. Wählt man den Punkt mit dem geringsten X-Wert als Startpunkt für z.B. Grahams-Scan, so liefert der Algorithmus die Punkte der konvexen Hülle entgegen dem Uhrzeigersinn. Somit werden die Punkte aufsteigend anhand ihres X-Wertes (und damit aufsteigend anhand des ursprünglichen Wertes im Array) ausgegeben. 20 5.2 Computergrafiken Ein weiteres Anwendungsgebiet der konvexen Hülle sind 3D-Computergrafiken. Um diese erstellen zu können, wird in den meisten Fällen eine Triangulierung angewendet, da hierbei die Flächen über Dreiecke approximiert werden. Definition Triangulierung: Abbildung 19: 3D-Computergrafik durch Triangulierung Triangulierung bezeichnet die Zerlegung eines Raumes in Simplizes. Die Triangulierung einer Punktmenge p1 , . . . , pn ∈ Q ist die simpliziale Zerlegung der konvexen Hülle von p1 , . . . , pn , die genau die gegeben Punkte als Eckpunkte haben. [2] Definition Simplex: Ein Simplex, bzw. n-Simplex ist ein n-dimensionaler Hypertetraeder, in der Geometrie auch n-dimensionales Polytop genannt. Ein Simplex S ∈ Qd ist die konvexe Hülle von d + 1 Punkten xi , die nicht alle in einer Hyperebene liegen. [2] • 0D-Simplex = Punkt • 1D-Simplex = Kante • 2D-Simplex = Dreieck • 3D-Simplex = Tetraeder Abbildung 20: 0D-, 1D-, 2D- und 3D-Simplex Eine günstige Triangulierung ist die /textitDelaunay-Triangulierung, benannt nach dem russischen Mathematiker Boris Nikolajewitsch Delone (franz. Form des Nachnamens: Delaunay). 21 Diese ist ein gebräuchliches Verfahren, um aus einer Punktmenge, ein Dreiecksnetz zu erstellen. Bei dieser speziellen Triangulierung erfüllen die einzelnen Simplizes die Umkreis- bzw. Umkugelbedingung. [2] Umkreis- bzw. Umkugelbedingung: Diese Bedingung gibt an, dass der Umkreis eines Dreiecke des Dreiecksnetzes keine weiteren Punkte der Punktmenge enthält. Hieraus folgt, dass die Innenwinkel der Dreiecke möglichst gros̈ (und somit auch konvex) sind, was in der Computergrafik sehr von Vorteil ist, da so Rundungsfehler vermieden werden können. [7] Die Delaunay-Triangulierung kann mit Hilfe der konvexen Hülle berechnet werden. Hierbei Abbildung 21: Umkreisbedingung nicht erfüllt Abbildung 22: Umkreisbedingung erfüllt wird jeder 2D-Punkt um eine z-Koordinate mit z = x2 + y 2 erweitert. Um die daraus dann resultierenden 3D-Punkte wird die konvexe Hülle erstellt. Werden nun alle nach unten orientierten Dreiecke (das sind diese, mit negativer z-Koordinate) in die ursprüngliche xy-Ebene zurückprojiziert, entsteht dadurch das gewünschte 2D-Dreiecksnetz. [7] 22 Abbildungsverzeichnis 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Kreuzprodukt zweier Vektoren ist die Fäche, die zwischen den Punkten (0|0), p1 , p2 und der Summe der beiden. . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Je nach Ergebnis des Kreuzprodukts zweier Vektoren, liegen die beiden Vektoren zueinander. Hier sieht man die unterschiedlichen Bereiche. . . . . . . . 3 Kreuzprodukt der Vektoren p#‰1 , p#‰2 ist > 0 . . . . . . . . . . . . . . . . . . . . 3 Kreuzprodukt der Vektoren p#‰1 , p#‰2 ist < 0 . . . . . . . . . . . . . . . . . . . . 4 #‰ Das Kreuzprodukt der Vektoren p1, p#‰2 ist < 0 . . . . . . . . . . . . . . . . . 5 Die Vektoren p# 0 p‰1 und p# 1 p‰2 können eine Links oder eine Rechtskurve darstellen. 6 Konvexe Menge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Nichtkonvexe Menge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Konvexes Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Sternförmiges Polygon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Konvexe Hülle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 konvexe Hülle von Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Graham’s scan Schritt für Schritt . . . . . . . . . . . . . . . . . . . . . . . . 12 Graham’s scan fertig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 Korrektheit Graham’s scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Jarvis’ march . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Konvexes Polytop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Konvexe Hülle der Punktemenge {(xi , xi 2 )} . . . . . . . . . . . . . . . . . . . 20 3D-Computergrafik durch Triangulierung . . . . . . . . . . . . . . . . . . . . 21 0D-, 1D-, 2D- und 3D-Simplex . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Umkreisbedingung nicht erfüllt . . . . . . . . . . . . . . . . . . . . . . . . . 22 Umkreisbedingung erfüllt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 Literatur [1] Mark de Berg u. a. Computational geometry: Algorithms and applications. 2., rev. ed. Berlin: Springer, 2000. isbn: 3-540-65620-0. [2] Computergrafik und Bildverarbeitung: Triangulierung. 2009. url: http://cg.inf.hbonn-rhein-sieg.de/wp-content/uploads/2009/04/cg_triangulierung.pdf. [3] Thomas H. Cormen u. a. Introduction To Algorithms. 3. Aufl. Cambridge, Massachusetts und London, England: The MIT Press, 2009. [4] Konvexität. 16.10.2003. url: http://www- lehre.inf.uos.de/~cg/2002/skript/ node33.html. [5] Hans Werner Lang und Fachhochschule Flensburg. Konvexe Hülle. 2016. url: http: //www.iti.fh-flensburg.de/lang/algorithmen/geo/convex.htm. [6] Vladimir S. Matveev. Konvexe Mengen. 2012. url: http://users.minet.uni-jena. de/~matveev/Lehre/LA2012/vorlesung8.pdf. [7] Wikipedia, Hrsg. Delaunay-Triangulierung. 7.01.2017. url: https://de.wikipedia. org/w/index.php?oldid=159309486. [8] Wikipedia, Hrsg. Polytop (Geometrie). 12.01.2017. url: https://de.wikipedia.org/ w/index.php?oldid=155852910. 23