Die Antwort hängt vom Kontext ab : Wenn Sie nur eine kleine (begrenzte) Anzahl von Segmenten untersuchen, können Sie sich möglicherweise eine rechenintensive Lösung leisten. Es ist jedoch wahrscheinlich, dass Sie diese Berechnung in eine Art Suche nach guten Beschriftungspunkten einbeziehen möchten. In diesem Fall ist es von großem Vorteil, eine Lösung zu haben, die entweder rechnerisch schnell ist oder eine schnelle Aktualisierung einer Lösung ermöglicht, wenn das Kandidatenliniensegment geringfügig variiert wird.
Zum Beispiel : Angenommen , Sie eine systematische Suche durchzuführen beabsichtigtüber eine gesamte verbundene Komponente einer Kontur, dargestellt als eine Folge von Punkten P (0), P (1), ..., P (n). Dies würde durch Initialisieren eines Zeigers (Index in der Sequenz) s = 0 ("s" für "Start") und eines anderen Zeigers f (für "Ende") erfolgen, um der kleinste Index zu sein, für den Abstand (P (f), P (s))> = 100, und dann s so lange vorrücken, wie die Entfernung (P (f), P (s + 1))> = 100. Dies erzeugt eine Kandidatenpolylinie (P (s), P (s +) 1) ..., P (f-1), P (f)) zur Bewertung. Nachdem Sie die "Eignung" zur Unterstützung eines Labels bewertet haben, erhöhen Sie s um 1 (s = s + 1) und erhöhen f auf (sagen wir) f 'und s auf s', bis erneut eine Kandidatenpolylinie das Minimum überschreitet Es wird eine Spanne von 100 erzeugt, dargestellt als (P (s '), ... P (f), P (f + 1), ..., P (f')). Dabei werden die Eckpunkte P (s) ... P (s ' Es ist sehr wünschenswert, dass die Fitness schnell aktualisiert werden kann, wenn nur die abgelegten und hinzugefügten Eckpunkte bekannt sind. (Dieser Scanvorgang würde fortgesetzt, bis s = n; wie üblich muss f dabei erlaubt sein, von n zurück auf 0 zu "wickeln".)
Diese Überlegung schließt viele mögliche Fitnessmaße ( Sinuosität , Tortuosität usw.) aus, die ansonsten attraktiv sein könnten. Dies führt dazu, dass wir L2- basierte Kennzahlen bevorzugen , da diese normalerweise schnell aktualisiert werden können, wenn sich die zugrunde liegenden Daten geringfügig ändern. Eine Analogie zur Hauptkomponentenanalyse legt nahe, dass wir das folgende Maß haben (wobei klein besser ist, wie gewünscht): Verwenden Sie den kleineren der beiden Eigenwerte der Kovarianzmatrixder Punktkoordinaten. Geometrisch ist dies ein Maß für die "typische" Abweichung von Seite zu Seite der Eckpunkte innerhalb des Kandidatenabschnitts der Polylinie. (Eine Interpretation ist, dass seine Quadratwurzel die kleinere Halbachse der Ellipse ist, die die zweiten Trägheitsmomente der Eckpunkte der Polylinie darstellt.) Sie ist nur für Sätze kollinearer Eckpunkte gleich Null. Andernfalls wird Null überschritten. Es misst eine durchschnittliche Abweichung von Seite zu Seite relativ zur 100-Pixel-Grundlinie, die durch den Beginn und das Ende einer Polylinie erzeugt wird, und hat dadurch eine einfache Interpretation.
Da die Kovarianzmatrix nur 2 mal 2 ist, werden die Eigenwerte schnell durch Lösen einer einzelnen quadratischen Gleichung gefunden. Darüber hinaus ist die Kovarianzmatrix eine Summe der Beiträge von jedem der Eckpunkte in einer Polylinie. Daher wird es schnell aktualisiert, wenn Punkte entfernt oder hinzugefügt werden, was zu einem O (n) -Algorithmus für eine n-Punkt-Kontur führt: Dies lässt sich gut auf die in der Anwendung vorgesehenen sehr detaillierten Konturen skalieren.
Hier ist ein Beispiel für das Ergebnis dieses Algorithmus. Die schwarzen Punkte sind Eckpunkte einer Kontur. Die durchgezogene rote Linie ist das beste mögliche Polyliniensegment mit einer End-to-End-Länge von mehr als 100 innerhalb dieser Kontur. (Der visuell offensichtliche Kandidat oben rechts ist nicht lang genug.)
In der Computergrafik-Community ist es häufig erforderlich, einen Begrenzungsrahmen um ein Objekt zu finden. Folglich ist dies ein gut untersuchtes Problem mit schnellen Algorithmen. Siehe beispielsweise den Artikel über Mindestbegrenzungsrahmenalgorithmen von Wikipedia . Sie können das Rechteck mit der minimalen Fläche finden, das Ihre Polylinie umgibt, und dann das Seitenverhältnis des Rechtecks, Höhe / Länge, verwenden. Um ein genaueres Maß zu erhalten, können Sie die Abweichung der Polylinie von der Mittellinie dieses Begrenzungsrechtecks betrachten.
quelle
Ich weiß nicht, ob dies hilft oder ob es als Antwort gilt, aber als ich hier saß und über die Frage nachdachte, die ich gerade gestellt habe, hatte ich einen Gedanken:
Was ist, wenn Sie einen Kreis mit einem bestimmten Radius auf Ihrer Konturlinie platzieren? Dieser Kreis schneidet die Konturlinie an mindestens zwei Stellen. Je gerader die Linie ist, desto kürzer ist der Abstand entlang der Konturlinie zwischen den beiden Schnittpunkten. Je länger der Abstand entlang der Konturlinie zwischen den Schnittpunkten ist, desto gekrümmter ist die Linie. Wenn es mehr als zwei Schnittpunkte gibt, ist die Konturlinie viel zu kurvig.
Sie können herausfinden, welche Länge den besten Indikator für die Geradheit liefert, und eine Routine einrichten, um entlang jeder Konturlinie zu gehen und das Etikett dort zu platzieren, wo es gerade genug ist.
Ich bin mir sicher, dass dies nicht allzu viel hilft, und was ich auf Englisch sage, ist in der von Ihnen verwendeten Programmiersprache viel schwieriger, aber es könnte ein Anfang sein?
quelle
Der einfachste Ansatz, den ich mir vorstellen kann, ist das Verhältnis zwischen der tatsächlichen Pfadlänge zwischen Start und Ende und dem kürzesten Abstand (gerade Linie) vom Anfang bis zum Endpunkt. Gerade Linien haben Verhältnisse nahe eins, während sehr gekrümmte Linien ein sehr hohes Verhältnis haben.
Dies sollte eine wirklich einfach zu implementierende Lösung sein.
Update: Wie Mike richtig bemerkte, würde dies Sinuosity entsprechen .
quelle
Durch die Suche nach "Krümmung" und "Polylinie" habe ich diese Informationen erhalten. Wie kann ich die Krümmung einer Polylinie finden? . Dort schlug er vor, zur Definition der Krümmung zurückzukehren
- K= DF/Ds
. HierF
meint erphi
oderT
in Wikipedia-Notation hier ( http://en.wikipedia.org/wiki/Curvature ).Angenommen, Sie haben eine Sequenz mit drei Punkten, p0, p1 und p2. Berechnen Sie den Abstand
s
zwischen p0 und p1, der das Delta von s (Ds
) ist, unter der Annahme, dass die Punkte nahe genug beieinander liegen. Dann benötigen Sie das Delta von T (DT
), dh die Änderung des Einheitstangentialvektors zwischen p0 und p1. Es mag einen ausgeklügelten Weg geben, aber die grobe Methode, die ich mir vorstellen kann, zwei Bektoren p0-> p1, p1-> p2 zu nehmen, jede auf eine Länge von eins zu normalisieren und dann die Vektorsubtraktion dieser beiden zu nehmen und dann die Größe zu bestimmen. Das istDT
. Division ergeben eine KrümmungK0_1
. Nimm p1, p2 und p3 zum BerechnenK1_2
und so weiter.Ich frage mich jedoch, ob Sie die Kontur als Polylinie und nicht als gerenderte Pixel erfassen. Du hast 100px gesagt, damit ich mir ein bisschen Sorgen mache.
quelle