Поворот матрицы к кватернионной эквивалентности

Я отслеживаю 3 точки (3D, XYZ) на твердом теле, которые я использую для определения локальной системы координат. Я использую эту локальную систему координат (в глобальной системе координат), чтобы установить ориентацию вида в программе VR. Чтобы сделать это и избежать блокировки карданного подвеса с углами Эйлера, я пытаюсь использовать кватернион для установки ориентации вида.

Я создаю матрицу вращения из 3 точек, а затем использую этот метод, описанный в Википедии, чтобы извлечь предполагаемый эквивалент кватерниона. Затем я просто устанавливаю ориентацию вида как вычисленный кватернион.

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

Мой вопрос заключается в том, почему предполагаемый эквивалент кватерниона, по-видимому, только изменяет степень свободы "основного тона"?

Я знаю, что кватернион - это вращение вокруг 1 оси, однако я подумал, что если он получен из матрицы вращения, конечный результат будет таким же, как при установке углов Эйлера?

Вот мой код в Python:

import viz
import numpy as np

vec1 = np.array([-0.96803,-0.25022,0.01751],dtype=float)
vec3 = np.array([-0.024815,0.96553,0.07863],dtype=float)
vec4 = np.array([-0.03655,0.07178,-0.99675],dtype=float)
#normalize to unit length
vec1 = vec1 / np.linalg.norm(vec1)
vec3 = vec3 / np.linalg.norm(vec3)
vec4 = vec4 / np.linalg.norm(vec4)

M1 = np.zeros((3,3),dtype=float) #rotation matrix

#rotation matrix setup
M1[:,0] = vec1
M1[:,1] = vec3
M1[:,2] = vec4

#get the real part of the quaternion first
r = np.math.sqrt(float(1)+M1[0,0]+M1[1,1]+M1[2,2])*0.5
i = (M1[2,1]-M1[1,2])/(4*r)
j = (M1[0,2]-M1[2,0])/(4*r)
k = (M1[1,0]-M1[0,1])/(4*r)

viz.MainView.setQuat(i,j,k,r)

Любая помощь или идеи будут великолепны!

1 ответ

Решение

Ключевая проблема здесь заключается в том, что вы применили алгоритм, который относится только к правильным матрицам вращения 3х3, к матрице, которая не ортогональна и очень близка к неправильной матрице вращения. Именно последнее является ключевым источником ваших проблем.

Ваша матрица М1

array([[-0.9994477 , -0.02887993,  0.0164005 ],
       [-0.02958325,  0.99862763, -0.04323132],
       [ 0.01513678,  0.0436899 ,  0.99893047]])

Вы получите ерунду, если неправильно примените этот алгоритм для извлечения кватерниона из правильной матрицы вращения в эту неправильную матрицу. В частности, потому что M[2,1] примерно равно -M[1,2], M[0,2] примерно равно M[2,0], а также M[1,0] примерно равно M[0,1]вы получите то, что кажется почти чистым рулоном.

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

Другие вопросы по тегам