Hier ist eine Konturkarte, für die alle Polygone von Ebenen verfügbar sind.
Fragen wir uns, wie die Polygone geglättet werden sollen, wobei alle Scheitelpunkte an ihren exakten Positionen erhalten bleiben.
In der Tat wird die Kontur über Rasterdaten erstellt. Sie können dann vorschlagen, die Rasterdaten zu glätten, und daher wird die resultierende Kontur glatter. Beachten Sie, dass dies nicht wie gewünscht funktioniert, da die Glättungsfunktion wie der Gauß-Filter kleine Datenpakete entfernt und den Bereich der dritten Variablen ändert, z. B. die Höhe, die in meiner Anwendung nicht zulässig ist.
Eigentlich bin ich auf der Suche nach einem Teil des Codes (vorzugsweise in Python ), der das Glätten von 2D-Polygonen (jeder Typ: konvex, konkav, sich selbst schneidend usw.) einigermaßen schmerzlos (Codeseiten vergessen) und genau kann.
Zu Ihrer Information, es gibt eine Funktion in ArcGIS , die dies perfekt macht. Die Verwendung von kommerziellen Anwendungen von Drittanbietern ist jedoch nicht meine Wahl für diese Frage.
1)
Scipy.interpolate:
Wie Sie sehen, sind die resultierenden Splines (rot) nicht zufriedenstellend!
2)
Hier ist das Ergebnis des Code in bestimmten Verwendung hier . Es funktioniert nicht gut!
3)
Für mich sollte die beste Lösung etwa die folgende Abbildung sein, in der ein Quadrat allmählich geglättet wird, indem nur ein Wert geändert wird. Ich hoffe auf ein ähnliches Konzept zum Glätten jeglicher Form von Polygonen.
Erfüllung der Bedingung, dass der Spline die Punkte überschreitet:
4)
Hier ist meine Umsetzung von "Whubers Idee" Zeile für Zeile in Python auf seine Daten. Möglicherweise gibt es einige Fehler, da die Ergebnisse nicht gut sind.
K = 2 ist eine Katastrophe und so für k> = 4.
5)
Ich habe einen Punkt an der problematischen Stelle entfernt und der resultierende Spline ist jetzt identisch mit dem von Whuber. Aber es ist immer noch eine Frage, warum die Methode nicht für alle Fälle funktioniert?
6)
Eine gute Glättung für Whubers Daten kann wie folgt aussehen (gezeichnet von einer Vektorgrafiksoftware), wobei ein zusätzlicher Punkt nahtlos hinzugefügt wurde (vergleiche mit dem Update)
4):
7)
Im Ergebnis der Python-Version von Whubers Code finden Sie einige ikonische Formen:
Beachten Sie, dass die Methode für Polylinien anscheinend nicht funktioniert. Für die Eckpolylinie (Kontur) ist Grün das, was ich will, aber rot. Dies muss behoben werden, da Konturkarten immer Polylinien sind, obwohl geschlossene Polylinien wie in meinen Beispielen als Polygone behandelt werden können. Auch nicht, dass das in Update 4 aufgetretene Problem noch nicht behoben wurde.
8) [mein letzter]
Hier ist die endgültige Lösung (nicht perfekt!):
Denken Sie daran, dass Sie etwas für den Bereich tun müssen, auf den die Sterne zeigen. Mein Code enthält möglicherweise einen Fehler, oder die vorgeschlagene Methode muss weiterentwickelt werden, um alle Situationen zu berücksichtigen und die gewünschten Ergebnisse zu erzielen.
Antworten:
Die meisten Methoden zum Splinen von Folgen von Zahlen werden Polygone splinen. Der Trick besteht darin, die Splines an den Endpunkten reibungslos zu schließen. Um dies zu tun, "wickeln" Sie die Eckpunkte um die Enden. Dann spline die x- und y-Koordinaten getrennt.
Hier ist ein Arbeitsbeispiel in
R
. Es wird die Standardprozedur für kubischespline
Daten verwendet, die im Basisstatistikpaket verfügbar ist. Ersetzen Sie für mehr Kontrolle fast jedes Verfahren, das Sie bevorzugen: Stellen Sie einfach sicher, dass es durch die Zahlen verläuft (dh sie interpoliert), anstatt sie lediglich als "Kontrollpunkte" zu verwenden.Um seine Verwendung zu veranschaulichen, erstellen wir ein kleines (aber kompliziertes) Polygon.
Spline es mit dem vorhergehenden Code. Erhöhen Sie die Anzahl der Scheitelpunkte von 100, um den Spline glatter zu machen. Verringern Sie die Anzahl der Scheitelpunkte, um die Glättung zu verringern.
Um die Ergebnisse zu sehen, zeichnen wir (a) das ursprüngliche Polygon in rotem Strich und zeigen die Lücke zwischen dem ersten und dem letzten Scheitelpunkt (dh ohne die Grenzpolylinie zu schließen); und (b) der Spline ist grau und zeigt wieder seine Lücke. (Da die Lücke so klein ist, werden ihre Endpunkte mit blauen Punkten hervorgehoben.)
quelle
Ich weiß, dass dies ein alter Beitrag ist, aber er wurde bei Google für etwas angezeigt, nach dem ich gesucht habe, und deshalb dachte ich, ich würde meine Lösung veröffentlichen.
Ich sehe dies nicht als eine 2D-Kurvenanpassungsübung, sondern als eine 3D-Übung. Indem wir die Daten als 3D betrachten, können wir sicherstellen, dass sich die Kurven niemals kreuzen, und Informationen aus anderen Konturen verwenden, um unsere Schätzung für die aktuelle zu verbessern.
Der folgende iPython-Extrakt verwendet die von SciPy bereitgestellte kubische Interpolation. Beachten Sie, dass die von mir gezeichneten z-Werte nicht wichtig sind, solange alle Konturen einen gleichen Höhenabstand aufweisen.
Die Ergebnisse hier sehen nicht gut aus, aber mit so wenigen Kontrollpunkten sind sie immer noch perfekt gültig. Beachten Sie, wie die grüne angepasste Linie herausgezogen wird, um der breiteren blauen Kontur zu folgen.
quelle
Ich habe fast genau das Paket geschrieben, nach dem Sie suchen ... aber es war in Perl und vor über einem Jahrzehnt: GD :: Polyline . Es verwendete kubische Bezier-2D-Kurven und "glättete" ein beliebiges Polygon oder eine beliebige Polylinie (mein Name war damals das, was heute allgemein als "LineString" bezeichnet wird).
Der Algorithmus bestand aus zwei Schritten: Fügen Sie unter Berücksichtigung der Punkte im Polygon zwei Bezier-Steuerpunkte zwischen jedem Punkt hinzu. Rufen Sie dann einen einfachen Algorithmus auf, um den Spline stückweise zu approximieren.
Der zweite Teil ist einfach; Der erste Teil war ein bisschen Kunst. Hier war die Erkenntnis: betrachtet ein „Steuersegment“ einen Vertex N:
vN
. Das Steuersegment war drei kolineare Punkte[cNa, vN, cNb]
. Der Mittelpunkt war der Scheitelpunkt. Die Steigung dieses Kontrollsegments war gleich der Steigung von Vertex N-1 bis Vertex N + 1. Die Länge des linken Abschnitts dieses Segments betrug 1/3 der Länge von Vertex N-1 bis Vertex N, und die Länge des rechten Abschnitts dieses Segments betrug 1/3 der Länge von Vertex N bis Vertex N + 1.Wenn die ursprüngliche Kurve vier Eckpunkten war:
[v1, v2, v3, v4]
dann wird jeder der Scheitelpunkt nun ein Steuersegment des Formulars erhalten:[c2a, v2, c2b]
. Ordnen Sie diese wie[v1, c1b, c2a, v2, c2b, c3a, v3, c3b, c4a, v4]
folgt an : und kauen Sie sie zu viert als die vier Bezier-Punkte:,[v1, c1b, c2a, v2]
dann[v2, c2b, c3a, v3]
und so weiter. Da[c2a, v2, c2b]
sie kolinear waren, ist die resultierende Kurve an jedem Scheitelpunkt glatt.Dies entspricht also auch Ihrer Anforderung, die "Enge" der Kurve zu parametrisieren: Verwenden Sie einen kleineren Wert als 1/3 für eine "engere" Kurve, einen größeren für eine "lockerere" Kurve. In beiden Fällen durchläuft die resultierende Kurve immer die ursprünglich angegebenen Punkte.
Dies führte zu einer glatten Kurve, die das ursprüngliche Polygon "umschrieb". Ich hatte auch eine Möglichkeit, eine glatte Kurve "einzuschreiben" ... aber ich sehe das nicht im CPAN-Code.
Jedenfalls habe ich momentan keine Version in Python und auch keine Zahlen. ABER ... wenn ich dies nach Python portiere, werde ich es hier veröffentlichen.
quelle