Erstellen Sie nicht-schneidende polygon Durchgang durch alle Punkte gegeben
Angenommen ich habe ein array von Punkten in zufälliger Reihenfolge, und ich muss ein polygon (durch Sortieren, so dass jedes benachbarte paar stellt eine Seite), die durch alle der Punkte, und seine Seiten sind nicht-schneidende natürlich.
Habe ich versucht zu tun, indem Sie einen Punkt, und die addition aller Punkte der final-array, die unter ihm sind, sortiert von Links nach rechts. Dann addiert man alle Punkte, die sind oben, sortiert von rechts nach Links.
Ich habe gesagt, dass, ich kann hinzufügen, ein weiterer Punkt Sortieren und natürlich zu vermeiden, selbst-Kreuzungen.. ich bin nicht in der Lage, herauszufinden, dass, obwohl. Was ist ein einfacher Weg, dies zu tun?
- Klingt wie das "Travelling Salesman Problem"
- Außer, dass die OP scheint nicht zu suchen den kürzesten Weg, aber für alle nicht selbst schneidet, ein. Ich glaube nicht, dass eine Optimierung nötig ist.
- Ich habe deutliche änderungen meiner Antwort. E-Mail mich, wenn Sie wollen, dass der Mathematica-code.
- hast u verwalten, um dieses Problem zu lösen?
- ich möchte, um Ihre Berechnungen. Wie kann ich Sie Kontaktieren?
- codie dot codemonkey bei gmail.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als jemand sagte, die minimale Länge-Lösung ist genau das traveling salesman problem. Hier ist eine nicht optimal, aber machbar-Ansatz:
Berechnen Sie ein Delauney-triangulation Ihrer Punkte. Sukzessive entfernen boundary-Segmente, bis Sie eine Grenze, die interpoliert werden alle Punkte oder gar keine mehr Segmente entfernt werden können. Entfernen Sie nicht die Grenze Segmente, wenn alle Punkte des Dreiecks mit diesem segment sind an der Grenze. Nehmen Sie diese Grenze als Ihren Weg.
Implementiert habe ich dies in Mathematica mit 40 zufällig gewählten Punkten. Hier ist ein typisches Ergebnis:
Den offensichtlichen Widerspruch ist, dass Sie vielleicht an einem Punkt, wo nicht alle deine Punkte sind Punkte-Grenze, aber Sie können nicht entfernen Sie eine segment Grenze, ohne die Grenze selbst zu schneiden. Das ist ein Gültiger Einwand. Es hat mich Dutzende runs machen, um zu sehen, einen Fall, wo das passiert ist, aber schließlich habe in diesem Fall:
Können Sie wahrscheinlich sehen einige offensichtliche Wege, dies zu beheben, mithilfe der lokalen Topologie, aber ich überlasse die details für Sie! Eine Sache, die helfen könnte, ist "edge flipping", wo man zwei Dreiecke, die eine Seite, sagen, Dreieck (p,q,r) und (q,p,s) und ersetzen Sie Sie mit (r,p,s) und (r,s,q) (alle Koordinaten gegen den Uhrzeigersinn um das Dreieck). Diese kann getan werden, solange die resultierenden Dreiecke in dieser transformation sind auch gegen den Uhrzeigersinn angeordnet.
Reduzieren die Notwendigkeit für fix-ups, werden Sie wollen, um eine gute Wahl der Segmente zu entfernen, bei jedem Schritt. Ich verwendet das Verhältnis der Länge der boundary segment der Summe der Längen der anderen Seite der Kandidat Dreieck (das Dreieck, gebildet durch die potenziell eingehende Punkt mit dem segment).
Quelle: http://www.cs.wustl.edu/~pless/546/Hausaufgaben/hw1_selectedProblems.pdf
Ich verstehe, das ist wirklich spät, aber es könnte nützlich sein, für zukünftige Betrachter.
Hier ist python 3.6-code (Bibliotheken erforderlich: matplotlib, numpy) basierend auf bdean20's Antwort.
Bilder Beschreibung:
Punkte.
=========
==========
Was Ihr sucht nennt sich eine einfach polygonization in der Literatur. Siehe, zum Beispiel, diese web-Seite auf das Thema.
Es ist einfach zu generieren eine star-shaped polygonization, wie Miguel sagt, aber schwierig
zu finden, zum Beispiel, einem minimalen Umfang polygonization, die eine minimale TSP, als Axel Kemper erwähnt. Es gibt im Allgemeinen eine exponentielle Anzahl verschiedener polygonizations für einen gegebenen Punkt gesetzt.
Zur sternförmigen polygonization, es ist ein Problem, das erfordert einige Aufmerksamkeit: der extra-Punkt x (in der "kernel" von der Stern) muss nicht übereinstimmen mit einem Punkt!
Hier ist ein Algorithmus zu garantieren x. Finden die nächsten beiden Punkte (a,b), und lassen Sie x den Mittelpunkt des Segments ab. Dann gehen Sie wie pro Miguel post.
Gut, wenn Sie nicht wirklich kümmern, minimality, oder ähnliches, können Sie legen Sie einfach einen neuen Punkt innerhalb der konvexen Hülle und dann um die anderen Punkte durch Winkel zu diesem neuen Punkt. Sie erhalten eine nicht-schneidende polygon.
Testen, ob zwei Segmente sich schneiden ist einfach und schnell. Sehen dass zum Beispiel.
Mit, die Sie bauen könnten, das polygon iterativ :
Quell-Punkte :
S = {S0, ... Si, Sj,...}
Final Polygon :
A = {A0, ... Ai, Aj,...}
Beginnen Sie mit
S
voll undA
leer.Nehmen Sie die ersten 3 Punkte der
S
und verschieben Sie Sie inA
. Dieses Dreieck ist natürlich nicht selbst schneiden.Dann, bis
S
leer ist, nehmen Sie Ihre erste noch der Punkt, dass wir rufenP
, und suchen Sie nach einer position inA
wo es eingefügt werden könnte.Diese position ist
i+1
für die ersteni
überprüfen, dass weder[Ai-P]
noch[Ai+1-P]
schneidet alle anderen Segmente[Ak-Ak+1]
.Ihre neue polygon
A
ist so{A0, ... Ai, P, Ai+1, ...}
Ich glaube, Sie verwenden können, Graham scan Algorithmus um Ihr problem zu lösen.
Edit: im Allgemeinen, Konvexe Hülle algorithmen sind etwas zu sehen.