Wie würde man die Länge eines Pfades bestimmen?

11

Ich habe ein Spiel, bei dem sich jeder Spieler auf einem bestimmten Pfad bewegen muss. Ich zeichne den Pfad mit Bézier-Kurven. Wie kann ich die gesamte reale (nicht lineare) Länge des Pfades und die Entfernung bestimmen, die jeder Spieler zurückgelegt hat? (Der Abstand zwischen dem Startpunkt und einem bestimmten Punkt auf dem Pfad.)

AKTUALISIEREN:

Der Pfad wird in einer kartesischen Ebene (2D) dargestellt.

Valentin Radu
quelle
Ihre Frage wird am Ende dieser Antwort beantwortet
BlueRaja - Danny Pflughoeft

Antworten:

7

Wie die vorherigen Antworten sagten, ist es schwierig ( unmöglich ?) , Die Länge einer Bezier-Kurve zu berechnen . Ich würde sagen, dass 100% der Spiele eine Annäherung an die Länge verwenden, die so ziemlich immer genau genug ist.

Vor einigen Monaten habe ich es mit dem vorgeschlagenen Ansatz implementiert, die Kurve in "kleine" Segmente zu unterteilen und deren Länge hinzuzufügen. Es ist ein Beispiel für ein C ++ Implementierung hier .

Dan
quelle
11

Das Messen der Länge einer Bezier-Kurve ist schwierig. Wenn Ihnen eine leichte Ungenauigkeit nichts ausmacht, besteht eine einfache Lösung darin, die Bezier-Kurven mit geraden Linien zu approximieren und die Summe der Linienlängen zu berechnen. Je mehr Segmente Sie erstellen, desto besser ist die Annäherung.

bummzack
quelle
Ich könnte das in Betracht ziehen, aber wie kann ich bestimmen, wie viele Segmente ich haben soll und wie kann ich die Segmente so zuordnen, dass ihr Start- und Endpunkt auf meinem Pfad liegen? Hat diese Technik einen Namen? (Also suche ich es bei Google)
Valentin Radu
Ein einfacher Ansatz wäre, einfach eine lineare Verteilung von Punkten von B (0) bis B (1) zu verwenden ... ähnlich wie etwas, das Sie zum tatsächlichen Zeichnen der Kurve verwenden würden. Schauen Sie sich den Quellcode in Dans Antwort an.
Bummzack
Ich würde mich über eine Erklärung der
Ablehnung freuen
7

Die Spline-Längenparametrisierung höherer Ordnung (dh größer als 1. Ordnung) muss angenähert werden. es kann nicht direkt dargestellt werden, daher ist es nicht einfach, direkte Lösungen dafür zu finden.

Einige vorhandene Implementierungen (Copy-Paste-Code):

Bei Verwendung von Chebyshev-Näherungen steigt nach Angaben der Autoren die Genauigkeit mit zunehmender Kurvengröße. Schauen Sie sich S. 7-8 Pseudocode an, der Rest ist eine Beschreibung anderer Algorithmen, auf denen sie ihren Ansatz basieren, den Sie ignorieren können. Eine Reihe von Online-Referenzen bezeichnen diese Methode als gut.

Siehe auch diese prägnanten Ansätze.

Ingenieur
quelle
5

Dies begann als Kommentar zum Kommentar zu @ bummzacks Antwort, wurde aber zu lang.

Wie kann ich bestimmen, wie viele Segmente ich haben soll?

Es gibt zwei Ansätze. Der erste ist nur der Standardalgorithmus zum Rendern einer Bézier-Kurve: Die Kontrollpunkte bilden einen Begrenzungsrahmen der Kurve. Wenn sich also alle Kontrollpunkte innerhalb von Epsilon des Liniensegments vom Startpunkt bis zum Endpunkt befinden, nähern Sie sich als Linie an. Andernfalls unterteilen Sie mit dem Algorithmus von de Casteljau. Epsilon wird entsprechend dem Fehler ausgewählt, den Sie im Endergebnis wünschen. (Zum Rendern sind es normalerweise 0,5 Pixel).

Der andere Ansatz ist eine Verfeinerung unter Verwendung der Intervallarithmetik. Nehmen Sie die Länge der Linie von Anfang bis Ende als Untergrenze und die Summe der Längen der Linien durch die Kontrollpunkte als Obergrenze. Unterteilen Sie erneut, wie es Ihre endgültigen Fehleranforderungen erfordern.

Normalerweise unterteilt man bei t = 0,5, aber der Algorithmus von de Casteljau erlaubt das Teilen an jedem Punkt. Wenn Sie also einen kubischen Bézier mit den Kontrollpunkten C_0 bis C_3 und C_2 haben, ist das Liniensegment zwischen den Endpunkten viel näher als bei C_1 Eine von 1/3 oder 2/3 gibt engere Grenzen. Ich habe die Algebra nicht durchgearbeitet, um zu rechtfertigen, welche besser wäre, aber Sie können experimentieren und Bericht erstatten, wenn Sie möchten. Wenn nichts anderes, wollte ich darauf hinweisen, dass die Option da ist.

Peter Taylor
quelle
3

Die Berechnung der Länge einer parametrisierten Kurve kann erfolgen, indem das Integral von sqrt ((dx / dt) ² + (dy / dt) ²) genommen wird, wobei dx / dt die Ableitung der x-Komponente der Kurve ist, und dy / dt ist die Ableitung der y-Komponente der Kurve. Im Fall eines Bézier-Splines sind diese beiden identisch, da die Gleichung auf jede Dimension erweitert werden kann.

Die Formel für einen kubischen Bézier-Spline lautet wie folgt: B (t) = (1 - t³) * P0 + 3 (1 - t) ²t * P1 + 3 (1 - t) t² * P2 + t³ P3 wobei P0 bis P3 sind die Kontrollpunkte.

Nach Wolfram | Alpha lautet die Ableitung dieser Formel: d (B (t)) / dt = 3 (t (t (P3 - P0) + P2 (2 - 3t) + P1 (3t² - 4t + 1))

Jetzt können Sie dies wieder in die Gleichung für die Länge einer Kurve einfügen und das Integral von t = 0 bis t = 1 berechnen. Leider tritt bei Wolfram | Alpha eine Zeitüberschreitung auf, wenn ich dies versuche. Sie können jedoch eine numerische Integration durchführen.

Ruud
quelle