2015-03-20 5 views
0

Я хотел бы сделать преобразование координат в евклидовом пространстве путем вращения. Это я хотел бы сделать, найдя матрицы, которые выравнивают текущую ось z в направлении заданного входного вектора. В этот момент эти вращения не дают удовлетворительного выхода.numpy огромная ошибка в преобразовании вращательных координат

import numpy as np 

vec_in = np.array([1*np.tan(np.pi/180*45), 1*np.tan(np.pi/180*45), 1]) 
vec_in /= np.linalg.norm(vec_in) #normalize, so we can use np.dot as scalar product 
print vec_in 

#find angles between vec_in and our x and y axis 
#avoid inverse trigonometric functions, thereby increase accuracy 
cosx = np.dot(vec_in, np.array([1,0,0])) 
sinx = np.sqrt(1-cosx**2) 
cosy = np.dot(vec_in, np.array([0,1,0])) 
siny = np.sqrt(1-cosy**2) 

#turn around z to bring x fraction to zero 
Rz = np.array([[cosx,-sinx,0], [sinx,cosx,0], [0,0,1]]) 
Rzi = np.linalg.inv(Rz) 
print 'accuracy Rz\n', np.dot(Rz, Rzi) 

#turn around y to align z to vector 
Ry = np.array([[cosy,0,siny], [0,1,0], [-siny,0,cosy]]) 
Ryi = np.linalg.inv(Ry) 
print 'accuracy Ry\n', np.dot(Ry, Ryi) 

print np.dot(Ryi, np.dot(Rzi, vec_in)), '\tshould be [1,0,0]' 
print np.dot(Rz, np.dot(Ry ,[0,0,1])), '\tshould be', vec_in 

выход:

[ 0.57735027 0.57735027 0.57735027] 
accuracy Rz 
[[ 1.00000000e+00 5.55111512e-17 0.00000000e+00] 
[ 0.00000000e+00 1.00000000e+00 0.00000000e+00] 
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]] 
accuracy Ry 
[[ 1.00000000e+00 0.00000000e+00 -7.70426082e-17] 
[ 0.00000000e+00 1.00000000e+00 0.00000000e+00] 
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]] 
[-0.0067889 -0.13807119 0.99039904] should be [1,0,0] 
[ 0.47140452 0.66666667 0.57735027] should be [ 0.57735027 0.57735027 0.57735027] 

Из np.dot(Rx,Rxi) я заключаю сейчас, что обратные матрицы работают достаточно хорошо; только фактический результат совсем не похож на то, что я ожидал бы. Зачем? Как я получу то, что хочу?

ответ

4

Вы должны сначала повернуть вектор вокруг оси y так, чтобы он лежал на плоскости xy, которую я назвал v1. Без нормализации v1 должен быть [sqrt (2), 1, 0]. (что составляет cosy,)

Затем поверните v1 так, чтобы он также лежал на плоскости xz. поэтому он находится на оси x.

import numpy as np 

vec_in = np.array([1*np.tan(np.pi/180*45), 1*np.tan(np.pi/180*45), 1]) 
vec_in /= np.linalg.norm(vec_in) #normalize, so we can use np.dot as scalar product 
print vec_in 

#find angles between vec_in and our x and y axis 
#avoid inverse trigonometric functions, thereby increase accuracy 

cosy = vec_in[0]/np.sqrt((vec_in[2]**2+vec_in[0]**2)) 
siny = np.sqrt(1-cosy**2) 

#turn around y to align z to vector 
Ry = np.array([[cosy,0,siny], [0,1,0], [-siny,0,cosy]]) 
Ryi = np.linalg.inv(Ry) 
print 'accuracy Ry\n', np.dot(Ry, Ryi) 

v1 = Ry.dot(vec_in) #z = 0 
cosx = v1[0]/np.sqrt((v1[1]**2+v1[0]**2)) 
sinx = np.sqrt(1-cosx**2) 

#turn around z to bring x fraction to zero 
Rz = np.array([[cosx,-sinx,0], [sinx,cosx,0], [0,0,1]]) 
Rzi = np.linalg.inv(Rz) 
print 'accuracy Rz\n', np.dot(Rz, Rzi) 


print np.dot(Rzi, np.dot(Ry, vec_in)), '\tshould be [1,0,0]' 
+0

Ваш код дает правильное решение. Несмотря на ваше описание, вы по-прежнему используете вращения вокруг z и y, которые в этом случае не имеют значения для данного примера вектора. Я намеревался обернуть другие оси и приказы, в основном следуя той же идее. Разница заключается в углах 'cosx',' sinx' - как бы вы предложили их вычислить с учетом произвольного 'vec_in'? – Faultier

+0

Привет, я изменил код для общего случая. Просто протестирован с помощью случайного 'vec_in' вручную. – lanpa

+0

Это работает. Я, по-видимому, рассчитывал неправильные углы. Спасибо за помощь! – Faultier

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