So finden größte Dreieck in der konvexen Hülle abgesehen von brute-force-Suche
Gegeben ein konvexes polygon, wie finde ich die 3 Punkte definieren, dass ein Dreieck mit den größten Raum ein.
Verwandte: Ist es wahr, dass der Umkreis des Dreiecks würde auch definieren das minimale umschließende Kreis des Polygons?
- ist dieses Hausaufgaben?
- Nein, ich arbeite auf Kollisionserkennung von polygonalen Formen für iPhone-Spiele. Die minimum bounding circle würde mir pflücken die Menge der potenziell kollidierenden Formen, bevor weitere teure polygon-polygon-Schnittpunkt-tests. In dem Prozess, ich bin zu lernen, computational geometry-algorithmen und deren Umsetzung in Objective-C. ... In Zukunft werde ich wahrscheinlich nur eine Physik-Bibliothek, aber ich will wissen, wie es funktioniert von Grund auf.
- Ich habe festgestellt, dass zu viel detail in einer Frage, die ist schlimm wie die Menschen neigen dazu, eine Antwort auf die interessantesten (implizit) eher Fragen auf, als Sie das sagte, man wenn es "zu einfach". Als Neuling, nichts ist einfach.
- Hinweis: die Beantwortung der sekundären Fragestellung aber nicht die primäre. Sorry, Sie rufen Stephan, es ist meine Schuld für den Versuch, für eine zwei-fer.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja, das kannst du deutlich besser als brute-force.
Durch brute-force-ich nehme an, du meinst die überprüfung alle Tripel von Punkten, und Kommissionierung die mit den maximalen Bereich. Diese läuft in O(n3) Zeit, aber es stellt sich heraus, dass es möglich ist, es zu tun, nicht nur an O(n2)
aber in O(n) Zeit![Update: Ein Papier veröffentlicht im Jahr 2017 zeigte durch sein Beispiel, dass die O(n) Lösung funktioniert nicht für eine bestimmte Klasse von Polygonen. Sehen diese Antwort für weitere details. Aber die O(n2) - Algorithmus ist dennoch korrekt.]
Durch die erste Sortierung der Punkte /Berechnung der konvexen Hülle (in O(n log n) Zeit), wenn nötig, können wir davon ausgehen, haben wir die konvexe Fläche/Rumpf mit den Punkten zyklisch sortiert in der Reihenfolge erscheinen Sie in dem polygon. Rufen Sie die Punkte 1, 2, 3, ... , n. Let (Variablen) die Punkte A, B, und C, start (1, 2 und 3 jeweils (in der zyklischen Ordnung). Wir bewegen A, B, C, bis ABC ist der maximum-Fläche Dreieck. (Die Idee ist ähnlich zu der rotierende Bremssättel Methode, wie Sie bei der Berechnung der Durchmesser (farthest-pair-Mädchen).)
Mit A-und B-Feste, advance C (z.B. zunächst mit A=1, B=2, C ist erweitert durch C=3, C=4, ...), solange die Fläche eines Dreiecks erhöht, d.h., solange die Fläche(A,B,C) ≤ Area(A,B,C+1). Dieser Punkt C wird die eine, die maximiert die Fläche(ABC) für diejenigen, die festen A und B. (In anderen Worten, die Funktion Area(ABC) ist unimodalen als Funktion der C.)
Weiter Voraus B (ohne änderung der Ein-und C) wenn, das erhöht die Gegend. Wenn dem so ist, wiederum Voraus, C wie oben. Dann fahren Sie B erneut, wenn möglich, etc. Diese geben die maximale Fläche Dreieck mit A als einer der Eckpunkte.
(Den Teil bis hier sollte einfach sein, zu beweisen, und einfach tun dies separat für jede Eine würde geben, ein O(n2) - Algorithmus.)
Nun vorab wieder Ein, wenn es verbessert den Bereich, und so weiter.(Die Richtigkeit dieses Teil ist subtiler: Dobkin und Snyder gab einen Nachweis in Ihrem Papier, aber eine aktuelle Papier zeigt ein Gegenbeispiel. Ich habe nicht verstanden es noch nicht.)
Obwohl diese drei "verschachtelten" Schleifen, beachten Sie, dass B und C immer Voraus "vorwärts", und steigen Sie auf höchstens 2n-mal insgesamt (ähnlich Einem Fortschritt bei den meisten n-mal), also das ganze Ding läuft in O(n) Zeit.
Code-fragment, das in Python (übersetzung nach C sollte einfach sein):
Dieser Algorithmus erwies sich in Dobkin und Snyder, Auf eine Allgemeine Methode für die Maximierung und Minimierung unter bestimmten geometrischen Problemen, FOCS 1979, und der code oben ist eine direkte übersetzung Ihrer ALGOL-60-code. Entschuldigung für die while-if-break-Konstruktionen; es sollte möglich sein, Sie zu verwandeln in einfacher while-Schleifen.
die Beantwortung Ihrer Frage im Zusammenhang:
Den Umkreis des Dreiecks ist nicht unbedingt das minimum bounding circle des Polygons. Um dies zu sehen, betrachten wir ein sehr flaches gleichschenkliges Dreieck, sagen wir mit Ecken bei (0,0), (10,0) und (5,1). Die minimum bounding circle center (5,0) und radius 5, aber dieser Kreis nicht berühren den Scheitelpunkt bei (5,1), es ist also nicht der Umkreis. (Der Umkreis hat den Mittelpunkt (5,-12) und radius 13)
edit:
Wahl des kleineren der Umkreis oder der Kreis mit der antipodische Punkte der Durchmesser des polygon auch nicht ausreichen, weil es möglich ist, zu konstruieren, Polygone, Punkte, die außerhalb des Umkreises der maximale Dreieck. Betrachten Sie das pentagon mit den Eckpunkten an:
Das maximale Dreieck hat Eckpunkte an (-4,-1), (5, 0), und (-4, 1). Ihren Umkreis gehören nicht der Punkt (-5, 0).
Laut diese Papier, es gibt eine Klasse von konvexen Polygonen, in die der Algorithmus zitiert nach ShreevatsaR die Antwort ausfällt. Das Papier schlägt auch eine O(n log n) divide and conquer Algorithmus für die Lösung des Problems.
Scheinbar einfacher O(n2) - Algorithmus, in dem Sie bewegen Sie die Punkte B und C für alle Ein noch gültig ist.
vom http://www.wolframalpha.com/input/?i=triangle
Die Fläche eines Dreiecks = sqrt((a+b-c)(a-b+c)(-a+b+c)*(a+b+c)) /4
Wenn Sie c-angeschlossen an die end-Punkte in der konvexen polygon
und wenn a und b berühren würde Ihrer konvexen polygon
könnte man iterieren, um das polygon
ermöglicht ein, um zu wachsen und b zu schrumpfen, bis Sie Ihre maximale Fläche.
Ich würde beginnen Mitte zeigen und versuchen, jede Richtung für eine größere Fläche.
Ich weiß, dies ist eine alte post, aber durch einen Verweis auf die Antwort oben ich war in der Lage, den code zu modifizieren, die zur Maximierung der Fläche für eine n-sided polygon.
Beachten Sie: Die konvexe Hülle wurde gefunden mit Emgu OpenCV-Bibliothek. Ich bin mit
CvInvoke.ContourArea()
Methode zum berechnen des gegebenen Fläche eines Polygons. Dies ist in C# geschrieben. Es wird auch davon ausgegangen, dass die Punkte angeordnet sind, im Uhrzeigersinn. Dies kann angegeben werden in der MethodeCvInvoke.ConvexHull()
.Bereich Methode verwendet. Das könnte sich ändern, je nachdem, was notwendig ist, zu maximieren.