Получить матрицу вращения между двумя двумя матрицами преобразования (XNA)

На данный момент у меня есть система обнаружения маркеров для AR, она определяет маркеры в сцене и выдает матрицу преобразования камеры для каждого маркера в сцене.

Допустим, я нашел 2 маркера. Я пытаюсь найти матрицу поворота, которую мне придется применить к одному из маркеров, чтобы он соответствовал ориентации другого маркера.

Я подумал, что это должно быть так же, как вычисление матрицы преобразования одного маркера в другой и разложение преобразования для получения матрицы вращения Эйлера x, y, z, но я не могу заставить это работать. Я использую С# с XNA.

В коде:

 Matrix marker1 = markerTransforms[0];
 Matrix marker2 = markerTransforms[1];

 Matrix relativeTransform = Matrix.Invert(marker1) * marker2;

 Quaternion rotation;
 Vector3 scale;
 Vector3 translation;
 relativeTransform.Decompose(out scale, out rotation, out translation);
 Matrix rotationMatrix = Matrix.CreateFromQuaternion(rotation);

Это выше, похоже, не работает.

Другой вопрос: как извлечь эйлеровы вращения x, y, z из матрицы вращения?

РЕДАКТИРОВАТЬ:

Я нашел здесь функцию для преобразования кватерниона в эйлеров порядок x, y, z: http://forums.create.msdn.com/forums/p/4574/23763.aspx

Применив это к моему коду, я получил следующие результаты:

введите здесь описание изображения

Фактическое вращение должно быть: x:0 y:0 z:-0.52

Я также заметил, что y и z сильно меняются в зависимости от того, как я расположил камеру.

Две матрицы преобразования, которые я получаю от детектора маркеров, содержат ориентацию и перемещение камеры относительно одного из маркеров, как описано здесь: http://www.hitl.washington.edu/artoolkit/documentation/tutorialcamera.htm Я преобразовал их в формат XNA и знаю, что они работают правильно, так как умею рисовать углы на экране, и это совпадает с тем, что видит камера.


person Jkh2    schedule 03.06.2012    source источник
comment
Я почти уверен, что углы Эйлера вычисляются правильно, но они даны в системе координат, относящейся к камере. Но вы хотите получить углы Эйлера относительно горизонтальной плоскости, не так ли?   -  person fdermishin    schedule 04.06.2012


Ответы (1)


Решение, которое мне больше всего нравится, это использование кватернионов. Если у вас есть одна ориентация, описанная q1, а другая — q2, вы можете перейти от одной ориентации к другой с помощью

q1=q*q2

это q ротация, которую вы ищете.

q = q1 * (q2)^-1; q = q1 * conj(q2);

Вам просто нужно преобразовать вращение в кватернион и кватернион в вращение.

Просто убедитесь, что вы нормализуете кватернионы, чтобы эквивалентности были верны. На страницах, на которые я ссылаюсь, есть все необходимые формулы, пояснения, даже код на Java, C++. Действительно стоит добавить в избранное.

person Jav_Rock    schedule 04.06.2012