Możliwe jest przybliżenie rozwiązania tego problemu dla większości trajektorii parametrycznych. Pomysł jest następujący: jeśli powiększysz wystarczająco głęboko krzywą, nie możesz odróżnić samej krzywej od jej stycznej w tym punkcie.
Przyjmując to założenie, nie ma potrzeby wstępnego obliczania niczego więcej niż dwóch wektorów (trzy dla sześciennych krzywych Beziera itp. .).
Dla krzywej M(t) obliczamy jej wektor styczny dMdt w punkciet. Normą tego wektora jest∥dMdT∥a zatem odległość przebytą przez czasΔtmożna określić w przybliżeniu jako∥dMdT∥Δt. Wynika z tego, że przebywa się odległośćLna czasL÷∥dMdT∥.
Zastosowanie: kwadratowa krzywa Beziera
Jeśli punktami kontrolnymi krzywej Beziera są A , B i C , trajektorię można wyrazić jako:
M(t)=(1−t)2A+2t(1−t)B+t2C=t2(A−2B+C)+t(−2A+2B)+A
Więc pochodna to:
dMdt=t(2A−4B+2C)+(−2A+2B)
Musisz po prostu przechowywać wektory v⃗ 1=2A−4B+2C a v⃗ 2=−2A+2B gdzieś. Następnie, dla danego t , jeśli chcesz przejść o długość L , robisz:
t=t+Llength(t⋅v⃗ 1+v⃗ 2)
Sześcienne krzywe Beziera
To samo rozumowanie dotyczy krzywej z czterema punktami kontrolnymi A , B , C i D :
M(t)=(1−t)3A+3t(1−t)2B+3t2(1−t)C+t3D=t3(−A+3B−3C+D)+t2(3A−6B+3C)+t(−3A+3B)+A
Pochodna to:
dMdt=t2(−3A+9B−9C+3D)+t(6A−12B+6C)+(−3A+3B)
Wstępnie obliczamy trzy wektory:
v⃗ 1v⃗ 2v⃗ 3=−3A+9B−9C+3D=6A−12B+6C=−3A+3B
and the final formula is:
t=t+Llength(t2⋅v⃗ 1+t⋅v⃗ 2+v⃗ 3)
Accuracy issues
If you are running at a reasonable framerate, L (which should be computed according to the frame duration) will be sufficiently small for the approximation to work.
However, you may experience inaccuracies in extreme cases. If L is too large, you can do the computation piecewise, for instance using 10 parts:
for (int i = 0; i < 10; i++)
t = t + (L / 10) / length(t * v1 + v2);