Кватернион с ортогональной основы - PullRequest
5 голосов
/ 25 октября 2009

У меня есть снаряд, который движется по вектору скорости. Мне нужно убедиться, что объект всегда обращен в направлении вектора скорости. Кроме того, я представляю вращение объекта с использованием кватернионов, а не матриц.

Я знаю, что первым шагом является поиск ортогонального базиса:

forward = direction of velocity vector
up = vector.new(0, 1, 0)
right = cross(up, forward) 
up = cross(forward, right)

Как я могу преобразовать базис в кватернион вращения?

Решение

Заметьте, я хотел бы поблагодарить Ноэля Хьюза за то, что он дал ответ, но я хочу уточнить с моим собственным опытом. Псевдокод следует:

   vec3 vel = direction of velocity vector
   vec3 forward = (1, 0, 0)  // Depends on direction your model faces. See below.
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit // Already facing the right direction!
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (0, axis.y * sin(theta/2), axis.z * sin(theta/2), cos(theta/2)

Последний элемент кватерниона - это скалярная часть, первые три элемента - это мнимые части. Кроме того, приведенный выше псевдокод предполагает, что ваш объект в «пространстве модели» направлен вниз по положительной оси X. В моем случае объект фактически указывал на положительную ось Y, и в этом случае я сделал следующие изменения:

   vec3 vel = direction of velocity vector
   vec3 forward = (0, 1, 0)  // Note that y-component is now 1
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit 
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (axis.x * sin(theta/2), 0, axis.z * sin(theta/2), cos(theta/2)
   // Note that SECOND component above is now 0

Ответы [ 2 ]

3 голосов
/ 27 октября 2009

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

Вы на правильном пути. Нормализовать вектор скорости, (vx, vy, vz) / sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2) пересечь с ним ось x и нормализовать результат - (0, yn, zn) - это вращение ось для кватерниона. Угол поворота - это просто тета = обратный косинус vx / sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2). Результирующий кватернион равен

(0, yn, zn) sn (тета / 2) cos (тета / 2)

Дайте мне знать, если у вас есть какие-либо вопросы.

Ноэль Хьюз nhughes1ster@gmail.com

0 голосов
/ 25 октября 2009

Я бы взглянул на библиотеку vecmath (Java). Это было давно, и мы используем его в нашем сообществе. Он основан на 4 кортежах, и я был бы разочарован, если бы не было простых методов преобразования.

Я бы также написал модульные тесты для ожидаемых результатов. Очень легко запутать положительные и отрицательные, левые и правые, а также движущиеся / ссылочные рамки. Начните с простых (например, xyz), чтобы убедиться, что у вас есть правильный ответ.

...