Respuestas:
Aquí está mi intento. Los siguientes algoritmos están lejos de ser perfectos , pero son simples y creo que debería comenzar con esto, verificar si funcionan en su situación y cambiar a algo más rápido y / o más preciso más adelante.
La idea es la siguiente:
La curva de Bézier se parametriza mediante una función que F(t)
utiliza un conjunto de puntos de control y un parámetro variable t
. El número de puntos generadores no es importante.
La línea está parametrizada por dos puntos A
y B
.
Deje SAMPLES = 10
, por ejemplo,
Comience con t0 = 0
yt1 = 1
Dejar dt = (t1 - t0) / SAMPLES
Si dt < 1e-10
(o cualquier otra condición de precisión que le parezca adecuada), el algoritmo está terminado y la respuesta esF(t0)
.
Calcule una lista de SAMPLES + 1
puntos en la curva de Bézier:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
Encuentre qué punto L
con índice i
es el más cercano a la línea. Utilice cualquier método de distancia punto / línea que conozca, por ejemplo, la distancia cuadrada ||AB^L[i]A||² / ||AB||²
donde ^
denota el producto cruzado y ||…||
es la distancia.
Si i == 0
, establecer i = 1
; si i == SAMPLES
, estableceri = SAMPLES - 1
Dejar t1 = t0 + (i + 1) * dt
yt0 = t0 + (i - 1) * dt
Regrese al paso 3.
Esta vez tenemos dos curvas Bézier, parametrizadas por F(t)
y G(t)
.
Deje SAMPLES = 10
, por ejemplo,
Comenzar con t0 = 0
, t1 = 1
, s0 = 0
ys1 = 1
Dejar dt = (t1 - t0) / SAMPLES
Dejar ds = (s1 - s0) / SAMPLES
Si dt < 1e-10
(o cualquier otra condición de precisión que le parezca adecuada), el algoritmo está terminado y la respuesta esF(t0)
.
SI esta es la primera ejecución del ciclo:
6.1. Calcule una lista de SAMPLES + 1
puntos F
( ver arriba ).
6.2. Calcule una lista de SAMPLES + 1
puntos G
.
6.3. Encuentra qué par de puntos están más cerca uno del otro.
6.4. Actualización t0
, t1
, s0
, s1
como se ha visto anteriormente.
ELSE : alternativamente, calcule una lista de puntos en F
OR una lista de puntos en G
, luego encuentre qué punto en F
está más cerca G(s0)
y actualice t0
y t1
, O qué punto de G
está más cerca F(t0)
y actualice s0
y s1
.
Regrese al paso 3.
Por diseño, estos algoritmos siempre convergerán a un mínimo local. Sin embargo, no hay garantía de que converjan a la mejor solución. En particular, el algoritmo de curva de Bézier no es muy bueno en absoluto, y en el caso de que dos curvas estén cerca una de la otra en muchos lugares, desafortunadamente puede perderse la solución de lejos.
Pero como dije, antes de comenzar a pensar en soluciones más robustas, primero debe experimentar con esas simples.
1) Traslade todo a un eje, de modo que en lugar de tener que calcular la longitud de un punto, la 'línea', la 'línea' es, por ejemplo, el eje Y.
Entonces, dada una curva bezier, diría que depende del número de puntos de control.
Si hay tres, (inicio, 'control' y finalización), haría algún tipo de escaneo (digamos un par de porcentajes y luego refine entre los más cercanos (con un enfoque 'binario').
Más puntos probaría la pareja más cercana al (Eje Y traducido).
Estoy seguro de que un matemático puede darle la solución exacta (en matemáticas), pero si desea encontrar la solución / a en un videojuego, podría estar mejor con una solución ligeramente correcta, ya que la solución real podría contener varias respuestas ( Ni siquiera estoy hablando de poder de procesamiento).
Algunas respuestas de la página del blog Algorithmist , que encuentra correctamente el punto más cercano en la curva bezier cuadrática dada.
Para la curva de Bezier: caso de línea recta, la forma más precisa de encontrar la respuesta es hacer lo siguiente: