2009-10-12 4 views
14

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

ответ

27

Следующий код основан на кватернион (КЯ, QX, QY, кв), где порядок основан на буст кватернионах:

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.

+0

fyi this выглядит как интерпретация строк, для тех, кто смотрит на это. Он должен работать, как при переходе к OpenGL, так как результат столбца и основной строки получается в том же линейном массиве. Однако, если вы используете это с большой библиотекой столбцов для умножения на другую матрицу, вы можете получить проблемы в зависимости от того, как работает ваша библиотека. – johnbakers

+0

Ницца. Таким образом, повышение может сделать почти все, что я нахожу. – 2013-09-01 14:59:24

+0

См. Также: http://stackoverflow.com/questions/1274936/flipping-a-quaternion-from-right-to-left-handed-coordianates, в котором упоминается, что Quaternions НЕ имеют ручности, но эти матрицы DO. Таким образом, вам, возможно, придется изменить 6 ячеек вышеуказанного преобразования, сопрягая их сорта. Ячейки 21, 31, 32, 12, 13, 23. (Помимо этого, я просто вставил этот код и немного изменил его для своей конкретной библиотеки, и он отлично поработал. Спасибо!) –

9

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

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

+0

Да, я забыл, что я мог бы сделать это ... Я дам ему идти – Polaris878

+0

Математически правильно, но вычислительно больше дорого сделать это так. – teodron

+0

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

3

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

// 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

Ссылка мертва. – Dan

0

с использованием GLM, вы можете просто использовать оператор литья. так, чтобы преобразовать из matrix4 в кватернион, просто написать

GLM :: mat4_cast (quaternion_name)

Смежные вопросы