Преобразовать кватернионное вращение в матрицу вращения? - PullRequest
17 голосов
/ 12 октября 2009

В основном, учитывая кватерион (qx, qy, qz, qw) ... Как я могу преобразовать это в матрицу вращения OpenGL? Мне также интересно, какая строка матрицы имеет значение «Вверх», «Вправо», «Вперед» и т. Д. У меня есть поворот камеры в кватернионе, который мне нужен в векторах ...

Ответы [ 4 ]

30 голосов
/ 12 октября 2009

Следующий код основан на кватернионе (qw, qx, qy, qz), где порядок основан на усилении кватернионов:

boost::math::quaternion<float> quaternion;
float qw = quaternion.R_component_1();
float qx = quaternion.R_component_2();
float qy = quaternion.R_component_3();
float qz = quaternion.R_component_4();

Сначала нужно нормализовать кватернион:

const float n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw);
qx *= n;
qy *= n;
qz *= n;
qw *= n;

Тогда вы можете создать свою матрицу:

Matrix<float, 4>(
    1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
    2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
    2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f);

В зависимости от вашего класса матрицы, вам может понадобиться транспонировать его перед передачей в OpenGL.

9 голосов
/ 12 октября 2009

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

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

2 голосов
/ 27 ноября 2013

Возможно, вам вообще не придется иметь дело с матрицей вращения. Вот способ, который кажется более быстрым, чем преобразование в матрицу и умножение вектора на нее:

  // move vector to camera position co (before or after rotation depending on the goal)
  v -= co;

  // rotate vector v by quaternion q; see info [1]
  vec3 t = 2 * cross(q.xyz, v);
  v = v + q.w * t + cross(q.xyz, t);

[1] http://mollyrocket.com/forums/viewtopic.php?t=833&sid=3a84e00a70ccb046cfc87ac39881a3d0

0 голосов
/ 28 декабря 2013

используя glm, вы можете просто использовать оператор приведения. чтобы преобразовать матрицу 4 в кватернион, просто напишите

GLM :: mat4_cast (quaternion_name)

...