#python #numpy #linear-algebra #coordinate-systems #euler-angles
#python #numpy #линейная алгебра #системы координат #углы Эйлера
Вопрос:
Я ищу, чтобы найти матрицу вращения для получения трех (почти) ортогональных векторов в одной и той же ориентации мировой системы координат.
Мои три (почти) ортогональных вектора могут быть представлены следующим образом в python:
vectors = np.array([[ 0.43187079, 0.90161148, 0.02417362],
[-0.46076794, 0.19750816, 0.86526495],
[ 0.77535832, -0.38482109, 0.50073167]])
Код, который я использую в настоящее время, может заставить векторы быть параллельными мировым координатам, но ориентация неправильная. Запуск этого кода,
xrotation = np.arctan2(vectors[2, 1], vectors[2, 2])
xRot = np.array([[1, 0, 0],
[0, np.cos(xrotation), -np.sin(xrotation)],
[0, np.sin(xrotation), np.cos(xrotation)]])
vectors_x = np.zeros((3, 3))
for i in range(3):
vectors_x[i, :] = np.linalg.inv(xRot.transpose()) @ vectors[i, :]
yrotation = np.arctan2(vectors_x[1, 2], vectors_x[1, 0])
yRot = np.array([[np.cos(yrotation), 0, np.sin(yrotation)],
[0, 1, 0],
[-np.sin(yrotation), 0, np.cos(yrotation)]])
vectors_y = np.zeros((3, 3))
for i in range(3):
vectors_y[i, :] = np.linalg.pinv(yRot.transpose()) @ vectors_x[i, :]
zrotation = np.arctan2(vectors_y[0, 0], vectors_y[0, 1])
zRot = np.array([[np.cos(zrotation), -np.sin(zrotation), 0],
[np.sin(zrotation), np.cos(zrotation), 0],
[0, 0, 1]])
vectors_z = np.zeros((3, 3))
for i in range(3):
vectors_z[i, :] = np.linalg.pinv(zRot.transpose()) @ vectors_y[i, :]
Дает три повернутых ортогональных вектора:
>vectors_z
>array([[-1.11022302e-16, 1.00000000e 00, 3.19660393e-09],
[ 1.00000000e 00, -3.70417658e-09, -2.77555756e-16],
[ 2.12261116e-09, -1.98949113e-09, -1.00000000e 00]])
Что мне нужно изменить в коде, чтобы получить его в правильной ориентации, которая будет выглядеть:
array([[ 1, 0, 0],
[ 0, 1, 0],
[ 0, 0, 1]])
Я знаю, что это можно получить, повернув векторы на 90/180 градусов в правильном порядке, но должен быть более эффективный способ сделать это, выполнив что-то еще в приведенном выше коде.
Спасибо за ваше время!!!
Ответ №1:
Понял это. Переключился на шаблон поворота ZYZ и переделал метод вычисления угла Эйлера. Надеюсь, это когда-нибудь кому-нибудь поможет.
import numpy as np
def z_rotation(zrotation):
z1Rot = np.array([[np.cos(zrotation), -np.sin(zrotation), 0],
[np.sin(zrotation), np.cos(zrotation), 0],
[0, 0, 1]])
return z1Rot
def y_rotation(yrotation):
yRot = np.array([[np.cos(yrotation), 0, np.sin(yrotation)],
[0, 1, 0],
[-np.sin(yrotation), 0, np.cos(yrotation)]])
return yRot
def forward_rotation(Rot,vectors_in):
vectors = np.zeros((3, 3))
for i in range(3):
vectors[i, :] = vectors_in[i, :] @ Rot
return vectors
def reverse_rotation(Rot, vectors_in):
vectors = np.zeros((3, 3))
for i in range(3):
vectors[i, :] = np.linalg.pinv(Rot.transpose()) @ vectors_in[i, :]
return vectors
org_vectors = np.array([[1,0,0],[0,1,0],[0,0,1]])
z1_angle = (-.5 np.random.random()) * 1800
y_angle = (-.5 np.random.random()) * 1800
z2_angle = (-.5 np.random.random()) * 1800
z1 = z1_angle*np.pi/180
y = y_angle*np.pi/180
z2 = z2_angle*np.pi/180
z1Rot = z_rotation(z1)
z1vectors = forward_rotation(z1Rot, org_vectors)
yRot = y_rotation(y)
yvectors = forward_rotation(yRot, z1vectors)
z2Rot = z_rotation(z2)
z2vectors = forward_rotation(z2Rot, yvectors)
z2angle_calc = np.arctan2(z2vectors[2,1],z2vectors[2,0])
z2rot_2 = z_rotation(z2angle_calc)
new_y = forward_rotation(z2rot_2, z2vectors)
yangle_2 = np.arctan2(new_y[2,0],new_y[2,2])
yrot_2 = y_rotation(yangle_2)
new_z1 = forward_rotation(yrot_2, new_y)
z1angle_2 = yangle_2 = np.arctan2(new_z1[0,1],new_z1[0, 0])
z1rot_2 = z_rotation(z1angle_2)
new_org_vectors = forward_rotation(z1rot_2, new_z1)
print(new_org_vectors)