Antworten:
Hier ist mein Versuch. Die folgenden Algorithmen sind alles andere als perfekt , aber sie sind einfach, und ich glaube, Sie sollten damit beginnen, prüfen, ob sie in Ihrer Situation funktionieren, und später zu etwas Schnellerem und / oder Genauerem wechseln.
Die Idee ist die folgende:
Die Bézier-Kurve wird durch eine Funktion F(t)
mit einer Reihe von Kontrollpunkten und einem variierenden Parameter parametrisiert t
. Die Anzahl der Erzeugungspunkte ist unwichtig.
Die Linie wird durch zwei Punkte A
und parametriert B
.
Lassen Sie SAMPLES = 10
zum Beispiel
Beginnen Sie mit t0 = 0
undt1 = 1
Lassen dt = (t1 - t0) / SAMPLES
Wenn dt < 1e-10
(oder eine andere Genauigkeitsbedingung, die Sie für richtig halten), ist der Algorithmus beendet und die Antwort lautetF(t0)
.
Berechnen Sie eine Liste von SAMPLES + 1
Punkten auf der Bézier-Kurve:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
Finden Sie den Punkt L
mit Index i
, der der Linie am nächsten liegt. Verwenden Sie eine beliebige bekannte Punkt- / Linienentfernungsmethode , z. B. die Quadratentfernung, ||AB^L[i]A||² / ||AB||²
bei der ^
das Kreuzprodukt und ||…||
die Entfernung angegeben sind.
Wenn i == 0
, setze i = 1
; wenn i == SAMPLES
, setzei = SAMPLES - 1
Lass t1 = t0 + (i + 1) * dt
undt0 = t0 + (i - 1) * dt
Fahren Sie mit Schritt 3 fort.
Diesmal haben wir zwei Bézier-Kurven, die von F(t)
und parametriert werden G(t)
.
Lassen Sie SAMPLES = 10
zum Beispiel
Beginnen Sie mit t0 = 0
, t1 = 1
, s0 = 0
unds1 = 1
Lassen dt = (t1 - t0) / SAMPLES
Lassen ds = (s1 - s0) / SAMPLES
Wenn dt < 1e-10
(oder eine andere Genauigkeitsbedingung, die Sie für richtig halten), ist der Algorithmus beendet und die Antwort lautetF(t0)
.
WENN dies der erste Durchlauf der Schleife ist:
6.1. Berechnen Sie eine Liste von SAMPLES + 1
Punkten auf F
( siehe oben ).
6.2. Berechnen Sie eine Liste von SAMPLES + 1
Punkten auf G
.
6.3. Finden Sie heraus, welches Punktepaar am nächsten ist.
6.4. Update t0
, t1
, s0
, s1
wie oben zu sehen.
ELSE : alternativ eine Liste von Punkten berechnen auf F
oder eine Liste von Punkten auf G
, dann finden , welche auf den Punkt F
am nächsten ist , G(s0)
und zu aktualisieren t0
und t1
, OR , welcher Punkt der G
am nächsten ist , F(t0)
und zu aktualisieren s0
und s1
.
Fahren Sie mit Schritt 3 fort.
Diese Algorithmen konvergieren konstruktionsbedingt immer auf ein lokales Minimum. Es gibt jedoch keine Garantie dafür, dass sie zur besten Lösung konvergieren. Insbesondere der Bézier-Kurvenalgorithmus ist überhaupt nicht sehr gut, und wenn zwei Kurven an vielen Stellen nahe beieinander liegen, kann es sein, dass Sie die Lösung bei weitem verpassen.
Aber wie gesagt, bevor Sie über robustere Lösungen nachdenken, sollten Sie zuerst mit diesen einfachen experimentieren.
1) Verschieben Sie alles auf eine Achse. Sie müssen also nicht die Länge eines Punktes berechnen, sondern beispielsweise die Y-Achse.
Bei einer Bézierkurve würde ich sagen, dass es an der Anzahl der Kontrollpunkte liegt.
Wenn es drei gibt (Anfang, "Kontrolle" und Ende), würde ich eine Art Scan durchführen (sagen wir jeweils ein paar Prozent) und dann zwischen den nächsten verfeinern (mit einem "binären" Ansatz).
Weitere Punkte würde ich das Paar ausprobieren, das der (übersetzten Y-Achse) am nächsten war.
Ich bin sicher, ein Mathematiker kann Ihnen die exakte Lösung geben (in Mathematik), aber wenn Sie die / eine Lösung in einem Videospiel finden möchten, sind Sie vielleicht besser dran mit einer etwas ok Lösung, da die echte Lösung mehrere Antworten enthalten könnte ( Ich spreche nicht einmal von Rechenleistung.
Einige Antworten von der Algorithmist- Blogseite, die den nächstgelegenen Punkt auf der angegebenen quadratischen Bezierkurve korrekt findet.
Demo .
Für den Fall Bezier-Kurve - Gerade ist der genaueste Weg, die Antwort zu finden, der folgende: