Wie kann ich effizient feststellen, ob ein Polygon konvex, nicht konvex oder komplex ist?
Auf der man-Seite für XFillPolygon
:
Wenn
shape
ist Komplexe, der Pfad kann selbstschneidend sein. Beachten Sie, dass zusammenhängende deckungsgleiche Punkte im Pfad werden nicht behandelt, wie self-Kreuzung.Wenn
shape
ist Konvex, für jedes paar von Punkten innerhalb des Polygons, ist das Liniensegment verbindet Sie überschneidet sich nicht mit dem Pfad. Wenn vom AUFTRAGGEBER bekannt, Angabe Konvex können die Leistung verbessern. Wenn Sie angeben, Konvex für einen Weg, der nicht konvex ist, werden die Grafiken die Ergebnisse sind nicht definiert.Wenn
shape
ist Nonconvex, den Pfad nicht selbst schneiden, sondern die Form ist nicht ganz konvex. Wenn vom AUFTRAGGEBER bekannt, Angabe Nonconvex statt Komplexe kann die Leistung verbessern. Wenn Sie angeben, Nonconvex für ein sich selbst Schneidender Pfad, der Grafik-Ergebnisse sind nicht definiert.
Bin ich performance Probleme mit füllen XFillPolygon
und, wie die man-page schon andeutet, ist der erste Schritt, den ich nehmen will ist, geben Sie die richtige Form des Polygons. Ich bin derzeit mit Komplexe, um auf der sicheren Seite.
Gibt es einen effizienten Algorithmus, um festzustellen, ob ein polygon (definiert durch eine Reihe von Koordinaten) ist konvex, nicht konvex oder Komplex?
InformationsquelleAutor der Frage hhafez | 2009-01-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
HINWEIS: die Berechnung der konvexen Hülle der Menge der Punkte ist völlig unnötig, wenn Sie nur wollen, um zu bestimmen, ob eine Liste der Punkte, die ein polygon stellt ein konvexes polygon.
Sehen Geschenkpapier-Algorithmus:
Vorausgesetzt, alle Ihre Polygone gegen den Uhrzeigersinn, der moment, in dem Ihre nicht-Initiale polar-Winkel nach Links drehen, wissen Sie, es ist nicht konvex.
Konnte man sehen, wenn sich die Liniensegmente schneiden sich mit jeder anderen, um herauszufinden, ob das polygon ist Komplex (aber ich bin mir nicht sicher, ob das der Schnellste Weg).
InformationsquelleAutor der Antwort Eugene Yokota
Können Sie die Dinge viel einfacher, als das Gift-Wrapping-Algorithmus... das ist eine gute Antwort, wenn Sie eine Reihe von Punkten, w/o jede bestimmte Grenze und müssen feststellen, dass die konvexe Hülle.
Im Gegensatz dazu betrachten wir den Fall, wo das polygon nicht selbst schneidet, und es besteht aus einem Satz von Punkten in einer Liste, wo die aufeinander folgenden Punkte bilden die Grenze. In diesem Fall ist es viel einfacher, um herauszufinden, ob ein polygon konvex ist oder nicht (und du musst Sie nicht berechnen Sie alle Winkel, entweder):
Für jedes aufeinander folgende paar von Kanten des Polygons (jedes Tripel der Punkte) berechnen Sie die z-Komponente des Kreuzprodukt der Vektoren definiert durch die Kanten gerichtet sein, die Punkte in aufsteigender Reihenfolge. Nehmen Sie das Kreuzprodukt dieser Vektoren:
Polygon ist konvex, wenn die z-Komponenten der cross Produkte sind entweder alle positiv oder alle negativ. Ansonsten ist das polygon nonconvex.
Wenn es N Punkte, stellen Sie sicher, Sie berechnen N cross-Produkte, z.B. werden Sie sicher, dass die Drillinge (p[N-2],p[N-1],p[0]) und (p[N-1],p[0],p[1]).
Wenn das polygon selbst schneidet, dann scheitert es bei der technischen definition der Konvexität auch wenn seine gerichtete Winkel sind alle in die gleiche Richtung, dann ist die obige Ansatz nicht zum richtigen Ergebnis.
InformationsquelleAutor der Antwort Jason S
Wird die folgende Java-Funktion/- Methode ist eine Implementierung des beschriebenen Algorithmus in diese Antwort.
Der Algorithmus funktioniert garantiert so lange, wie die vertices angeordnet sind (entweder im Uhrzeigersinn oder gegen den Uhrzeigersinn), und Sie müssen sich nicht selbst schneidende Kanten (d.h. es funktioniert nur für einfache Polygone).
InformationsquelleAutor der Antwort Uri Goren
Diese Frage wird jetzt das erste Element in entweder Bing oder Google, bei der Suche nach "bestimmen, konvexen polygon." Jedoch, keiner der Antworten, die gut genug sind.
Die akzeptiert die Antwort von @EugeneYokota funktioniert, indem Sie prüfen, ob eine unsortierte Punkte, die gemacht werden können in ein konvexes polygon, aber das ist nicht das, was der OP gefragt. Er fragte nach einer Methode, um zu überprüfen, ob ein gegebenes polygon ist konvex oder nicht. (Ein "polygon" in der informatik ist in der Regel definiert als [in der XFillPolygon Dokumentation] als geordnetes array von 2D-Punkte, wobei aufeinanderfolgende Punkte verbunden mit einem Seite, als auch den letzten Punkt auf den ersten.) Auch die Geschenkverpackung Algorithmus würde in diesem Fall die Zeit-Komplexität von
O(n^2)
fürn
Punkte - das ist viel größer, als tatsächlich benötigt wird, um dieses problem zu lösen, während die Frage fragt nach einer effizienten Algorithmus.@JasonS Antwort, zusammen mit den anderen Antworten, die Folgen seiner Idee akzeptiert Sterne Polygone wie ein Pentagramm oder in @zenna Kommentar, aber Sterne Polygone nicht als konvex. Als
@plasmacel Hinweise in einem Kommentar, dies ist ein guter Ansatz zu verwenden, wenn Sie die Vorherige Kenntnis, dass das polygon nicht selbst schneiden, aber es kann fehlschlagen, wenn Sie nicht das wissen haben,.
@Sekhat Antwort ist richtig, aber es hat auch die Zeit-Komplexität von
O(n^2)
und damit ineffizient ist.@LorenPechtel ' s Antwort Hinzugefügt nach Ihr Bearbeiten ist das beste hier, aber es ist vage.
Einen korrekten Algorithmus mit der optimalen Komplexität
Den Algorithmus, den ich hier präsentieren, hat die Zeit-Komplexität von
O(n)
richtig testet, ob ein polygon konvex ist oder nicht, und übergibt alle tests, die ich geworfen haben. Die Idee ist, Durchlaufen Sie die Seiten des Polygons, wobei die Richtung jeder Seite und die unterschriebene änderung der Richtung zwischen zwei aufeinander folgenden Seiten. "Unterzeichnet" bedeutet hier Links-Gemeinde positiv ist, und rechts-die Gemeinde ist negativ (oder Umgekehrt) und straight ahead ist null. Die Winkel sind normalisiert zu sein, zwischen minus-pi (exklusive) und pi (inklusive). Fazit alle diese Richtung-ändern Sie die Winkel (ein.k.eine der Durchbiegung Winkel) zusammen Folge im plus-oder-minus eine umdrehung (d.h. 360 Grad) für ein konvexes polygon, während eine sternförmige polygon (oder eine selbst-schneidende Schleife) wird eine andere Summe ( n * 360 Grad, für n stellt sich insgesamt für die Polygone, wo alle die Durchbiegung Winkel sind von der gleichen Vorzeichen). Also müssen wir schauen, dass die Summe der Richtung-ändern der Winkel ist plus-oder-minus eine umdrehung. Wir prüfen auch, dass die Richtung-ändern-Winkel alle positiv oder alle negativ und nicht umkehrt (pi Bogenmaß), alle Punkte sind tatsächliche 2D-Punkte, und dass nicht aufeinander folgende Eckpunkte sind identisch. (Dieser Letzte Punkt ist umstritten-Sie können zulassen möchten wiederholt Eckpunkte, aber ich bevorzuge diese verbieten.) Die Kombination dieser Prüfungen fängt alle konvexen und nicht-konvexen Polygonen.Hier ist der code für Python 3 implementiert den Algorithmus und enthält einige kleinere Wirkungsgrade. Der code sieht mehr aus als es wirklich ist aufgrund der die Kommentarzeilen und die Buchführung, die beteiligten bei der Vermeidung von wiederholten point zugreift.
InformationsquelleAutor der Antwort Rory Daulton
Hier ist ein test, um zu überprüfen, ob ein polygon ist konvex.
Denken, dass jeder Satz von drei Punkten entlang des Polygons. Wenn jeder Winkel von 180 Grad oder weniger haben Sie ein konvexes polygon. Wenn Sie herausfinden, jeden Winkel, auch halten eine laufende Summe von (180 - Winkel). Für ein konvexes polygon, das wird insgesamt 360.
Dieser test läuft in O(n) Zeit.
Beachten Sie auch, dass in den meisten Fällen ist diese Berechnung etwas, das Sie tun können, sobald und sparen — die meisten der Zeit, die Sie haben eine Menge von Polygonen zu arbeiten, die sich nicht ständig ändern.
InformationsquelleAutor der Antwort Loren Pechtel
Um zu testen, ob ein polygon ist konvex, jeden Punkt des Polygons sollte auf einer Ebene mit oder hinter jeder Zeile.
Hier ein Beispiel Bild:
InformationsquelleAutor der Antwort Sekhat
Den Antwort von @RoryDaulton
scheint das beste für mich, aber was ist, wenn einer der Winkel genau 0?
Einige wollen so ein Grenzfall den Wert True zurück, ist in dem Fall ändern, "< = " zu "<" in der Zeile :
Hier sind meine test-Fällen, das highlight der Ausgabe :
Den 2. geltend machen, scheitert in der ursprünglichen Antwort. Sollte es?
Für meinen Gebrauch Fall würde ich es lieber nicht.
InformationsquelleAutor der Antwort nickthecoder
Ich implementierte algorithmen: die eine, gepostet von @UriGoren (mit einer kleinen Verbesserung - nur integer-math), und der von @RoryDaulton, in Java. Ich hatte einige Probleme, weil meine polygon geschlossen ist, so dass beide algorithmen wurden unter Berücksichtigung der zweiten als konkav, wenn konvex ist. Also änderte ich es zu verhindern, dass solche situation. Meine Methoden auch verwendet eine base index (der kann oder nicht 0 ist).
Diese sind meiner test-vertices:
Und nun die algorithmen:
Und nun von Uri Goren
InformationsquelleAutor der Antwort Guilherme Campos Hazan
Diese Methode funktionieren würde, auf einfache Polygone (keine selbst schneidenden Kanten) unter der Annahme, dass die Scheitelpunkte angeordnet sind (entweder im Uhrzeigersinn oder gegen)
Für ein array von vertices:
Den folgenden
python
Umsetzung überprüft, ob diez
Komponente aller cross-Produkte haben die gleichen VorzeichenInformationsquelleAutor der Antwort Uri Goren
Angepasst Uri ' s code in matlab. Hoffe das kann helfen.
Sich bewusst sein, dass Uri ' s Algorithmus funktioniert nur für einfache Polygone! So, sicher sein, um zu testen, ob das polygon ist einfach die erste!
InformationsquelleAutor der Antwort Peter K.T. Yu