Как интерполировать вращения? - PullRequest
9 голосов
/ 21 мая 2010

У меня есть два вектора, описывающие вращения; начальное вращение A и целевое вращение B. Как лучше всего интерполировать A с коэффициентом F, чтобы приблизиться к B?

Использование простого рычага для векторов не работает, когда необходимо интерполировать более одного измерения (то есть производить нежелательные повороты). Возможно, построение кватернионов из векторов вращения и использование slerp - лучший способ. Но как же тогда я могу извлечь вектор, описывающий новое вращение, из полученного кватерниона?

Заранее спасибо.

Ответы [ 4 ]

9 голосов
/ 21 мая 2010

Так как я, похоже, не понимаю ваш вопрос, вот небольшая SLERP реализация на python с использованием numpy. Я составил результаты с помощью matplotlib (v.99 для Axes3D). Я не знаю, можете ли вы использовать python, но похоже ли это на вашу реализацию SLERP? Мне кажется, чтобы дать хорошие результаты ...

from numpy import *
from numpy.linalg import norm

def slerp(p0, p1, t):
        omega = arccos(dot(p0/norm(p0), p1/norm(p1)))
        so = sin(omega)
        return sin((1.0-t)*omega) / so * p0 + sin(t*omega)/so * p1


# test code
if __name__ == '__main__':
    pA = array([-2.0, 0.0, 2.0])
    pB = array([0.0, 2.0, -2.0])

    ps = array([slerp(pA, pB, t) for t in arange(0.0, 1.0, 0.01)])

    from pylab import *
    from mpl_toolkits.mplot3d import Axes3D
    f = figure()
    ax = Axes3D(f)
    ax.plot3D(ps[:,0], ps[:,1], ps[:,2], '.')
    show()
4 голосов
/ 09 августа 2013

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

Есть два варианта:

Простые перекрестные продукты:

Определите ось n , которая ортогональна и А и В, используя перекрестное произведение (будьте осторожны, когда векторы выровнены) и вычислите угол a между А и В, используя точечный продукт. Теперь вы можете просто подойти к B, позволив a перейти от 0 к a (это будет aNew и применить вращение aNew о ось n по A.

Кватернионы:

Вычислите кватернион q , который перемещает A к B, и интерполируйте q с идентичным кватернионом I , используя SLERP. Полученный кватернион qNew затем можно применить к A.

2 голосов
/ 21 мая 2010

Что ж, ваш подход к Slerp будет работать и, вероятно, наиболее эффективен в вычислительном отношении (даже если его немного сложно понять). Чтобы вернуться от кватернионов к вектору, вам нужно использовать набор формул, которые вы можете найти здесь .

Здесь также есть немного соответствующего кода здесь , хотя я не знаю, соответствует ли он тому, как представлены ваши данные.

1 голос
/ 21 мая 2010

Если вы решили использовать Quaternions (который очень хорошо справляется), посмотрите мой ответ здесь о ресурсах для реализации Quaternions: Вращение в OpenGL относительно области просмотра

Вы можете найти множество примеров в ссылках в этом посте.

...