Es posible aproximar una solución a este problema para la mayoría de las trayectorias paramétricas. La idea es la siguiente: si hace un zoom lo suficientemente profundo en una curva, no puede distinguir la curva en sí de su tangente en ese punto.
Al hacer esta suposición, no es necesario calcular previamente nada más que dos vectores (tres para curvas de Bezier cúbicas, etc. ).
Entonces, para una curva calculamos su vector tangente en el punto . La norma de este vector es y, por lo tanto, la distancia recorrida durante una duración puede aproximarse como . Se deduce que se recorre una distancia durante un tiempo .METRO( t )reMETROrett∥ dMETROreT∥Δ t∥ dMETROreT∥ Δ tLL ÷ ∥ dMETROreT∥
Aplicación: curva de Bezier cuadrática
Si los puntos de control de la curva de Bezier son , y , la trayectoria se puede expresar como:UNAsido
METRO( t )= ( 1 - t )2A + 2 t ( 1 - t ) B + t2do= t2( A - 2 B + C) + t ( - 2 A + 2 B ) + A
Entonces la derivada es:
reMETROret= t ( 2 A - 4 B + 2 C) + ( - 2 A + 2 B )
Solo necesita almacenar los vectores y alguna parte. Luego, para una determinada , si desea avanzar una longitud , debe:v⃗ 1=2A−4B+2Cv⃗ 2= - 2 A + 2BtL
t = t + Ll e n gt h ( t ⋅ v⃗ 1+ v⃗ 2)
Curvas de Bezier cúbico
El mismo razonamiento se aplica a una curva con cuatro puntos de control , , y :UNAsidore
METRO( t )= ( 1 - t )3A + 3 t ( 1 - t )2B + 3 t2( 1 - t ) C+ t3re= t3( - A + 3 B - 3 C+ D ) + t2( 3 A - 6 B + 3 C) + t ( - 3 A + 3 B ) + A
La derivada es:
reMETROret= t2( - 3 A + 9 B - 9 C+3D)+t(6A−12B+6C)+(−3A+3B)
Calculamos previamente los tres vectores:
v⃗ 1v⃗ 2v⃗ 3=−3A+9B−9C+3D=6A−12B+6C=−3A+3B
y la fórmula final es:
t=t+Llength(t2⋅v⃗ 1+t⋅v⃗ 2+v⃗ 3)
Problemas de precisión
Si está ejecutando a una velocidad de cuadro razonable, (que debe calcularse de acuerdo con la duración del cuadro) será lo suficientemente pequeño para que la aproximación funcione.L
Sin embargo, puede experimentar imprecisiones en casos extremos. Si es demasiado grande, puede hacer el cálculo por partes, por ejemplo, utilizando 10 partes:L
for (int i = 0; i < 10; i++)
t = t + (L / 10) / length(t * v1 + v2);