Wie Sie in der Abbildung sehen, lautet die Frage:
Wie finde ich das Minimum-Area-Rectangle (MAR), das auf die gegebenen Punkte passt?
und eine unterstützende Frage ist:
Gibt es eine analytische Lösung für das Problem?
(Eine Weiterentwicklung der Frage wird darin bestehen, ein Kästchen (3D) an einen Punktcluster in einer 3D-Punktwolke anzupassen.)
Als erstes schlage ich vor, die konvexe Hülle für die Punkte zu finden, die das Problem reformieren (indem diese Punkte entfernt werden, die nicht in der Lösung enthalten sind), um: einen MAR an ein Polygon anzupassen. Die erforderliche Methode liefert X ( Mittelpunkt des Rechtecks ), D ( zwei Dimensionen ) und A ( Winkel ).
Mein Lösungsvorschlag:
- Ermitteln des Schwerpunkts des Polygons (siehe Ermitteln des Mittelpunkts der Objektgeometrie? )
- [S] Passen Sie ein einfaches angepasstes Rechteck an, dh parallel zu den Achsen X und Y
- Sie können die
minmax
Funktion für X und Y der angegebenen Punkte verwenden (z. B. die Eckpunkte des Polygons).
- Sie können die
- Speichern Sie den Bereich des angepassten Rechtecks
- Drehen Sie das Polygon um z. B. 1 Grad um den Schwerpunkt
- Wiederholen Sie diesen Vorgang ab [S], bis eine vollständige Drehung erfolgt ist
- Geben Sie als Ergebnis den Winkel der minimalen Fläche an
Es scheint mir vielversprechend, aber die folgenden Probleme bestehen:
- Die Wahl einer guten Auflösung für die Winkeländerung könnte eine Herausforderung sein.
- der Rechenaufwand ist hoch,
- Die Lösung ist nicht analytisch, sondern experimentell.
Als Ergänzung zu der großartigen Lösung von @ julien gibt es hier eine funktionierende Implementierung in
R
, die als Pseudocode für jede GIS-spezifische Implementierung dienen kann (oderR
natürlich direkt in angewendet werden kann). Die Eingabe ist ein Array von Punktkoordinaten. Die Ausgabe (der Wert vonmbr
) ist ein Array der Eckpunkte des minimalen Begrenzungsrechtecks (wobei der erste wiederholt wird, um es zu schließen). Beachten Sie, dass keine trigonometrischen Berechnungen vorliegen.Hier ist ein Beispiel für seine Verwendung:
Das Timing wird durch die Geschwindigkeit des konvexen Rumpfalgorithmus begrenzt, da die Anzahl der Scheitelpunkte im Rumpf fast immer viel geringer ist als die Gesamtzahl. Die meisten konvexen Rumpfalgorithmen sind asymptotisch O (n * log (n)) für n Punkte: Sie können fast so schnell berechnen, wie Sie die Koordinaten lesen können.
quelle
Ich habe das gerade selbst implementiert und meine Antwort auf StackOverflow gepostet , aber ich dachte, ich würde meine Version hier ablegen , damit andere sie sehen können:
Hier sind vier verschiedene Beispiele in Aktion. Für jedes Beispiel habe ich 4 zufällige Punkte generiert und den Begrenzungsrahmen gefunden.
Auch für diese Beispiele ist es in 4 Punkten relativ schnell:
quelle
points = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
, und die Ausgabe istarray([[1.00000000e+00, 6.12323400e-17], [0.00000000e+00, 0.00000000e+00], [6.12323400e-17, 1.00000000e+00], [1.00000000e+00, 1.00000000e+00]])
das Einheitsquadrat selbst (einschließlich einiger Gleitkomma-Rundungsfehler). Hinweis: Ein Quadrat ist nur ein Rechteck mit gleichen Seiten. Ich gehe also davon aus, dass es ein Quadrat verarbeiten kann, das auf alle Rechtecke verallgemeinert wird.In Whitebox GAT ( http://www.uoguelph.ca/~hydrogeo/Whitebox/ ) gibt es ein Tool namens Minimum Bounding Box, um genau dieses Problem zu lösen. Es gibt dort auch ein minimales Werkzeug für den konvexen Rumpf. Einige der Werkzeuge in der Patch-Form-Toolbox, z. B. Patch-Ausrichtung und -Dehnung, basieren auf der Ermittlung des minimalen Begrenzungsrahmens.
quelle
Ich bin auf diesen Thread gestoßen, als ich nach einer Python-Lösung für ein begrenzendes Rechteck mit minimaler Fläche gesucht habe.
Hier ist meine Implementierung , für die die Ergebnisse mit Matlab überprüft wurden.
Testcode ist für einfache Polygone enthalten, und ich verwende ihn, um den 2D-Mindestbegrenzungsrahmen und die Achsenrichtungen für eine 3D-Punktwolke zu finden.
quelle
Danke @ whubers Antwort. Es ist eine großartige Lösung, aber langsam für große Punktwolken. Ich fand, dass die
convhulln
Funktion im R-Paketgeometry
viel schneller ist (138 s gegenüber 0,03 s für 200000 Punkte). Ich habe hier meine Codes eingefügt, für die sich jemand für eine schnellere Lösung interessiert.Zwei Methoden erhalten die gleiche Antwort (Beispiel für 2000 Punkte):
quelle
Ich empfehle einfach die eingebaute OpenCV-Funktion
minAreaRect
, die ein gedrehtes Rechteck des minimalen Bereichs findet, der den 2D-Eingabepunktsatz einschließt. Informationen zur Verwendung dieser Funktion finden Sie in diesem Lernprogramm .quelle