0

Я пытаюсь случайным образом генерировать преобразования координат для подстановки, которые я пишу на python. Я хочу повернуть мои данные (кучу координат [x, y, z]) о происхождении, в идеале используя кучу случайно генерируемых нормальных векторов, которые я уже создал для определения плоскостей - я просто хочу сдвинуть каждую плоскость I определяется так, что оно лежит в плоскости z = 0.Преобразования координат из случайно сгенерированного вектора нормалей

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

import matplotlib as plt 
import numpy as np 
import math 

origin = np.array([35,35,35]) 
normal = np.array([np.random.uniform(-1,1),np.random.uniform(-1,1),np.random.uniform(0,1)]) 
mag = np.sum(np.multiply(normal,normal)) 
normal = normal/mag 

a = normal[0] 
b = normal[1] 
c = normal[2] 

#I know this is not the right transformation matrix but I'm not sure what is... 
#Looking for the steps that will take me from the normal vector to this transformation matrix 
rotation = np.array([[a, 0, 0], [0, b, 0], [0, 0, c]]) 

#Here v would be a datapoint I'm trying to shift? 
v=(test_x,test_y,test_z) 
s = np.subtract(v,origin) #shift points in the plane so that the center of rotation is at the origin 
so = np.multiply(rotation,s) #apply the rotation about the origin 
vo = np.add(so,origin) #shift again so the origin goes back to the desired center of rotation 

x_new = vo[0] 
y_new = vo[1] 
z_new = vo[2] 

fig = plt.figure(figsize=(9,9)) 
plt3d = fig.gca(projection='3d') 
plt3d.scatter(x_new, y_new, z_new, s=50, c='g', edgecolor='none') 
+0

Что вы хотите сказать? Работает ли текущий код или нет? Благодарю. –

+0

Мой вопрос: как получить правильную матрицу преобразования из нормального вектора? – Arnold

+0

Теперь я понимаю ваш вопрос.Несколько матриц преобразования могут дать вам правильный ответ, потому что вы можете вращать плоскость вокруг оси z. Возможно, попробуйте http://math.stackexchange.com/ вместо этого? –

ответ

0

Благодаря людям, участвующим в обмене математического стека, у меня есть ответ, который работает. Но обратите внимание, что это не сработает, если вам также понадобится выполнить перевод, чего я не сделал, потому что я определяю свои плоскости обычным вектором и точкой, а нормальный вектор меняется, но точка не работает. Вот что сработало для меня.

import matplotlib as plt 
import numpy as np 
import math 

def unit_vector(vector): 
    """ Returns the unit vector of the vector. """ 
    return vector/np.linalg.norm(vector) 

cen_x, cen_y, cen_z = 35.112, 35.112, 35.112 
origin = np.array([[cen_x,cen_y,cen_z]]) 

z_plane_norm = np.array([1,1,0]) 
z_plane_norm = unit_vector(z_plane_norm) 

normal = np.array([np.random.uniform(-1,1),np.random.uniform(-1,1),np.random.uniform(0,1)]) 
normal = unit_vector(normal) 

a1 = normal[0] 
b1 = normal[1] 
c1 = normal[2] 

rot = np.matrix([[b1/math.sqrt(a1**2+b1**2), -1*a1/math.sqrt(a1**2+b1**2), 0], [a1*c1/math.sqrt(a1**2+b1**2), b1*c1/math.sqrt(a1**2+b1**2), -1*math.sqrt(a1**2+b1**2)], [a1, b1, c1]]) 

init = np.matrix(normal) 

fin = rot*init.T 
fin = np.array(fin) 

# equation for a plane is a*x+b*y+c*z+d=0 where [a,b,c] is the normal 
# so calculate d from the normal 
d1 = -origin.dot(normal) 

# create x,y 
xx, yy = np.meshgrid(np.arange(cen_x-0.5,cen_x+0.5,0.05),np.arange(cen_y-0.5,cen_y+0.5,0.05)) 

# calculate corresponding z 
z1 = (-a1 * xx - b1 * yy - d1) * 1./c1 

#------------- 

a2 = fin[0][0] 
b2 = fin[1][0] 
c2 = fin[2][0] 

d2 = -origin.dot(fin) 
d2 = np.array(d2) 
d2 = d2[0][0] 

z2 = (-a2 * xx - b2 * yy - d2) * 1./c2 

#------------- 

# plot the surface 
fig = plt.figure(figsize=(9,9)) 
plt3d = fig.gca(projection='3d') 

plt3d.plot_surface(xx, yy, z1, color='r', alpha=0.5, label = "original") 
plt3d.plot_surface(xx, yy, z2, color='b', alpha=0.5, label = "rotated") 


plt3d.set_xlabel('X (Mpc)') 
plt3d.set_ylabel('Y (Mpc)') 
plt3d.set_zlabel('Z (Mpc)') 

plt.show() 

Если вам необходимо выполнить перевод, а также, посмотреть полный ответ, который я работал прочь here.

2

Я думаю, что у вас неправильная концепция матриц вращения. Матрицы вращения определяют вращение определенного угла и не могут иметь диагональную структуру.

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

R = Rz*Ry*Rx 
Rotated_item = R*original_item 

или

Rotated_item = np.multiply(R,original_item) 

В этой формуле Rx является первым приложенное вращения.
Имейте в виде, что

  • вы можете получить ротацию сочинения много другого набора из 3 вращения
  • последовательности она не является фиксированной, она может быть X-Y-Z или Z-Y-X или Z-X-Z или любая комбинация. Значения углов могут меняться, так как последовательность изменений
  • это «опасно» использование этой матрицы для вращения критических значений (90-180-270-360 градусов)

Как составить каждую отдельную матрицу поворота вокруг 1 ось? См. this image from wikipedia. У Numpy есть все, что вам нужно.

Теперь вам нужно определить значения трех углов. Конечно, вы можете получить 3-х угловые значения из случайного нормированного вектора (a, b, c), как вы пишете в своем вопросе, но поворот - это процесс, который преобразует вектор в другой вектор. Может быть, вам нужно указать что-то вроде «Я хочу найти вращение R вокруг начала координат, которое преобразует (0,0,1) в (a, b, c)». Совершенно иное вращение R 'является тем, которое преобразует (1,0,0) в (a, b, c).

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

  • Нет связанных вопросов^_^