2015-05-30 4 views
0

У меня есть (мировая) матрица, и она применяет перевод, поворот и масштаб в трехмерный объект. Он создается с помощью функции XMMatrixTransformation (DirectXMath), а параметр RotationQuaternion производится по вызову XMQuaternionRotationRollPitchYaw. Затем он сохраняется в файле вместе с другими данными.Есть ли способ конвертировать кватернион под углом?

Тогда мне нужно, чтобы восстановить значения, так что я могу использовать эту функцию, чтобы разложить его по каждому компоненту:

XMMatrixDecompose(&Scale, &RotationQ, &Translation, Matrix); 

Scale и перевод являются векторами и вращение кватернионов. Если матрица поворачивает объект в одной оси, я мог бы использовать это, чтобы преобразовать кватернион назад к углам:

XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ); 

Он отлично работает. Но когда он вращается в двух или более осях, как я могу сделать то же самое? Есть ли способ сделать это?

PS: Мне все равно, если выходные углы не совпадают с входом. Они просто должны быть эквивалентными.

PS2: Хорошо, поэтому я последовал за ссылкой Гена (я уже там посмотрел, но не нашел то, что мне было нужно в это время). Я сделал этот код, основанный в этом уравнении я нашел в Википедии: equation

float Roll = atan2(2.0*(F.x*F.y + F.z*F.w), 1 - 2 * (F.y*F.y + F.z*F.z)); 
float Pitch = asin(2.0*(F.x*F.z - F.w*F.y)); 
float Yaw = atan2(2.0*(F.x*F.w + F.y*F.z), 1 - 2 * (F.y*F.y + F.z*F.z)); 

В выходных у меня есть разные углы. Выход кажется эквивалентным для (90°, 0°, 90°), но не для (45°, 45°, 45°).

+0

См. Http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles – Gene

+0

Пожалуйста, подумайте, действительно ли вам нужны углы Эйлера. Есть очень мало случаев, и углы Эйлера - это боль для работы. –

ответ

1

У вас есть два варианта.

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

С другой стороны, если вам действительно нужно получить его как углы Эйлера, нет никакой хорошей функции, чтобы сделать это за вас. Однако формулы легко доступны. Материал из Википедии:

Quaternion to Euler formula

По определению Википедии, фита угол вокруг глобальной оси Z, тета угол вокруг «нормальной оси» N (ось, которая проходит через местное происхождение и ортогонален плоскость глобальной оси Z и конечная локальная ось Z - да, это странно странно), а psi - угол вокруг локальной (то есть повернутой) оси Z.

Если бы я был лучшим математиком, я мог бы помочь вам перевести это в простое вращение X, Y, Z в глобальном пространстве, но, к сожалению, это выходит за рамки моих возможностей.

Просто знайте, что не существует строгой корреляции 1-1 между кватернионами и углами Эйлера; gimbal lock означает, что есть определенные углы, которые имеют один и тот же угол Эйлера, например. Подумайте, действительно ли вам нужны углы Эйлера - в большинстве случаев поворот по осевому углу будет работать одинаково, без значительных проблем с углами Эйлера.

+0

Спасибо за ваш ответ. Для варианта один: я собираюсь использовать ось и угол, если я этого не понимаю. Благодарю.Для второго варианта: Нет, 'XMQuaternionRotationRollPitchYawFromVector'. Вычисляет кватернион вращения на основе вектора, содержащего углы Эйлера (шаг, рыскание и рулон). в соответствии с [MSDN] (https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.quaternion.xmquaternionrotationrollpitchyawfromvector (v = vs.85) .aspx). – LHLaurini

+0

Вы правы, это моя ошибка. К сожалению, не существует функции преобразования от кватернионов к углам Эйлера, ни от матрицы к углам Эйлера. Вы можете создать свою собственную функцию, используя образцы из [статьи Википедии] (http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles). В частности, http://upload.wikimedia.org/math/a/2/9/a2925987257bc7469187cfc3c18da853.png (где phi находится вокруг оси Z, theta находится вокруг X, а psi вокруг Y.) Я бы все же рекомендовал вам чтобы действительно подумать о том, хотите ли вы, углы Эйлера. –

+0

О, спасибо. Посмотрите, что я добавил к моему ответу. Я предполагал, что _φ_ (phi) был X, _θ_ (theta) равным Y, а _ψ_ (psi) - Z. Теперь попробуйте снова. PS: Я тупой. Я не видел, что «где ось X направлена ​​вперед, ось Y вправо и ось Z вниз» – LHLaurini