Określ długość łuku splajnu Catmull-Rom, aby poruszał się ze stałą prędkością


18

Mam ścieżkę, która jest zdefiniowana przez połączenie splajnów Catmull-Rom. Używam statycznej metody Vector2.CatmullRom w XNA, która pozwala na interpolację między punktami o wartości od 0 do 1.

Nie każdy splajn na tej ścieżce ma tę samą długość. Powoduje to różnice prędkości, jeśli pozwolę, aby ciężar poruszał się ze stałą prędkością dla każdego splajnu podczas podążania ścieżką. Mogę temu zaradzić, pozwalając, aby prędkość ciężaru była zależna od długości splajnu. Jak mogę określić długość takiego splajnu? Czy powinienem tylko przybliżać, przecinając splajn na 10 linii prostych i sumując ich długości?

Używam tego do dynamicznego mapowania tekstur na wygenerowanej siatce zdefiniowanej przez splajny.

Odpowiedzi:


25

Wygląda na to, że chcesz utrzymać prędkość obiektu na stałym poziomie na całej krzywej - znajomość długości łuku nie pomoże ci tego zrobić. Pomoże ci obliczyć, o której godzinie obiekt osiągnie punkt końcowy, gdyby jechał z tą prędkością, więc będzie lepszy niż to, co masz teraz (obiekt będzie miał taką samą średnią prędkość między wszystkimi punktami), ale rzeczywista prędkość obiektu będzie się nadal zmieniać w miarę przesuwania się po krzywej.

Lepszym rozwiązaniem byłaby zmiana naszego parametru parametrycznego (parametru, który zmienia się z 0 na 1, który wywołam, saby uniknąć pomyłki t = time) ze zmienną szybkością ds/dt, która zależy od prędkości, z jaką obiekt ma się poruszać ten punkt na krzywej. Innymi słowy, zamiast zmieniać so 0,01 każdej klatki, możemy ją zmienić o 0,005 jednej klatki, 0,02 następnej itd.

Robimy to, obliczając pochodne x( dx/ds) i y( dy/ds) każdej klatki, a następnie ustawiając

ds / dt = prędkość / sqrt ((dx / ds) 2 + (dy / ds) 2 )

Oznacza to, że biorąc prędkość, którą chcemy iść, i dzieląc przez prędkość, którą faktycznie byśmy osiągali, gdybyśmy zmieniali ssię z ustalonym przyrostem.


Dowód

Chcemy, aby prędkość naszego obiektu była stała; nazwijmy tę stałą nazwą speed.

Uczymy się w drugim roku nazębnego, że dla równań parametrycznych x(s)i y(s),

prędkość = sqrt ((dx / dt) 2 + (dy / dt) 2 )

Uczymy się również tego

dx / dt = dx / ds * ds / dt     (reguła łańcuchowa)

A zatem,

prędkość = sqrt ((dx / ds) 2 (ds / dt) 2 + (dy / ds) 2 (ds / dt) 2 )

Rozwiązując ds/dt, otrzymujemy podane równanie.


Obliczanie pochodnych

Nigdy nie pracowałem z tymi szczególnymi splajnami, ale rozumiem, że one po prostu dają x(s)i y(s)jeśli chodzi o równania sześcienne z s. W ten sposób możemy łatwo znaleźć pochodną dx/ds: if

x (s) = a * s 3 + b * s 2 + c * s + e

następnie

dx / ds = 3a * s 2 + 2b * s + c

(To samo dotyczy dy/ds) Oczywiście, trzeba znać dokładne wartości a, bi cto zrobić. Zgodnie z tą stroną wartości te można łatwo znaleźć.


Wreszcie, aby odpowiedzieć na pytanie w tytule: znalezienie równania długości łuku funkcji parametrycznej wymaga rozwiązania dość skomplikowanej całki oznaczonej ; nawet w prostym przypadku równania sześciennego nie można tego zasadniczo zrobić.

Zatem będziesz musiał oszacować całkę numerycznie . „Cięcie splajnu na 10 linii prostych i sumowanie ich długości”, jak sugerujesz, jest bardzo prostym sposobem na zrobienie tego ; istnieją jednak nieco bardziej skomplikowane metody, które zapewnią znacznie dokładniejsze wyniki przy użyciu mniejszej liczby segmentów linii.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.