Вопрос

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

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

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
Это было полезно?

Решение

Я предполагаю, что вас не волнует ориентация вашего снаряда, за исключением того, что продольная ось выровнена с вектором скорости, и что продольной осью является ось x из (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

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top