Определите длину дуги сплайна Кэтмулла-Рома, чтобы двигаться с постоянной скоростью

18

У меня есть путь, который определяется конкатенацией сплайнов Кэтмулла-Рома. Я использую статический метод Vector2.CatmullRom в XNA, который допускает интерполяцию между точками со значением от 0 до 1.

Не все сплайны на этом пути имеют одинаковую длину. Это вызывает разницу в скорости, если я позволю весу двигаться с постоянной скоростью для каждого сплайна, пока я продолжаю движение по траектории. Я могу исправить это, допустив, что скорость веса зависит от длины сплайна. Как я могу определить длину такого сплайна? Должен ли я просто аппроксимировать, разрезая сплайн на 10 прямых и суммируя их длины?

Я использую это для динамического наложения текстуры на сгенерированную сетку, определенную сплайнами.

Wouter
источник

Ответы:

25

Похоже, вы хотите поддерживать постоянную скорость объекта на протяжении всей кривой - знание длины дуги не поможет вам в этом. Это поможет вам рассчитать, в какое время объект достигнет своей конечной точки, если бы он двигался с этой скоростью, так что это будет лучше, чем у вас сейчас (объект будет иметь одинаковую среднюю скорость между всеми точками), но Фактическая скорость объекта будет по-прежнему изменяться при движении по кривой.

Лучшим решением было бы изменить наш параметрический параметр (параметр, который идет от 0 до 1, который я буду называть, sчтобы избежать путаницы t = time) с переменной скоростью ds/dt, которая определяется скоростью, с которой вы хотите, чтобы объект двигался эта точка на кривой. Другими словами, вместо изменения sна 0,01 каждый кадр, мы можем изменить его на 0,005 один кадр, 0,02 следующий и т. Д.

Мы делаем это, вычисляя производные x( dx/ds) и y( dy/ds) каждого кадра, затем устанавливая

ds / dt = скорость / sqrt ((dx / ds) 2 + (dy / ds) 2 )

То есть, взяв скорость, которую мы хотим достичь, и разделив ее на скорость, которую мы фактически достигли бы, если бы мы изменялись sс фиксированным шагом.


доказательство

Мы хотим, чтобы скорость нашего объекта была постоянной; давайте дадим этой константе имя speed.

Мы учимся в второй год исчисления , что для параметрических уравнений x(s)и y(s),

скорость = sqrt ((dx / dt) 2 + (dy / dt) 2 )

Мы также узнаем, что

dx / dt = dx / ds * ds / dt     (правило цепочки)

Таким образом,

скорость = sqrt ((дх / дс) 2 (дс / дт) 2 + (дд / дс) 2 (дс / дт) 2 )

Решая для ds/dt, мы получаем заявленное уравнение.


Расчет производных

Я никогда не работал с этими конкретными сплайнами, но я понимаю, что они просто дают x(s)и y(s)в терминах кубических уравнений s. Таким образом, мы можем dx/dsлегко найти производную : если

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

тогда

дх / дс = 3a * s 2 + 2b * s + c

( То же самое для dy/ds) Конечно, вам нужно знать точные значения a, bи cсделать это. Согласно этой странице , эти значения легко найти.


Наконец, чтобы ответить на вопрос в заголовке: для нахождения уравнения длины дуги параметрической функции необходимо решить довольно сложный определенный интеграл ; даже для простого случая кубического уравнения это вообще невозможно сделать.

Таким образом, вам придется оценивать интеграл численно . «Разрезание сплайна на 10 прямых и суммирование их длин», как вы предлагаете, - один из очень простых способов сделать это ; однако есть немного более сложные методы , которые дадут вам гораздо более точные результаты, используя меньше отрезков.

BlueRaja - Дэнни Пфлугхофт
источник