我正在尝试旋转vector1 (红色),以便它在3D空间中与vector2 (蓝色)对齐。但是,应仅使用绕X轴和Z轴的旋转。
到目前为止,我已经使用优化算法解决了这个问题,该算法试图最小化向量之间围绕X轴和Z轴的角度。这在大多数情况下都工作得很好,但由于我必须计算大量的向量,所以速度太慢。
我用于优化方法的代码:
vector1 = np.array([0., -1., 0.])
vector2 = np.array([0.2, -0.2, -0.5])
def find_a_c(x, *args):
vector1, vector2 = args[0], args[1]
angle_x, angle_z = x[0], x[1]
# Rotation matrices to rotate around X and Z
Rx = np.array([[1., 0., 0.],
[0., np.cos(angle_x), -np.sin(angle_x)],
[0., np.sin(angle_x), np.cos(angle_x)]])
Rz = np.array([[np.cos(angle_z), -np.sin(angle_z), 0.],
[np.sin(angle_z), np.cos(angle_z), 0.],
[0., 0., 1.]])
vector1 = vector1.dot(Rx).dot(Rz)
# calulate the angle between the vectors around X and Z
angle_x = angle_between_vectors([vector2[1], vector2[2]], [vector1[1], vector1[2]])
angle_z = angle_between_vectors([vector2[0], vector2[1]], [vector1[0], vector1[1]])
return np.abs(angle_x) + np.abs(angle_z)
solution = minimize(fun=find_a_c,
x0=[0., 0.],
args=(vector1, vector2))
angle_x, angle_z = solution.x[0], solution.x[1]
print("Angle around X: {}°\nAngle around Z: {}°".format(np.rad2deg(angle_x), np.rad2deg(angle_z)))
打印:
Angle around X: -60.46948402478365°
Angle around Z: -45.0000003467713°
现在我正在寻找一种分析方法来解决我的问题。例如,用两个旋转角(围绕X和Z)形成的旋转矩阵以将vector1与vector2对齐。
发布于 2020-05-26 21:04:59
这是一个相当数学的问题,我不确定如何在这里正确地写数学,但你可以做下面的事情。如果首先围绕X轴旋转,然后围绕Z轴旋转,则最后一次旋转不会更改z投影。如果(a, b, c)
是起始法线向量,(x, y, z)
是结束法线向量,则可以基于绕X轴的旋转矩阵编写b * sin(f) + c * cos(f) = z
,其中f
是绕X轴的旋转角度。然后基于equality from wikipedia (看起来不太正确:应该去掉sng(c)部分),你可以找到f
的值。因此,您可以计算X轴旋转矩阵,并在应用此旋转(a', b', c')
后获得向量。然后将其与Z轴旋转矩阵相乘,并为x
和y
写出等式,您可以得到Z轴旋转角度的sin和cos的值。
import numpy as np
vector1 = np.array([0., -1., 0.])
vector2 = np.array([0.2, -0.2, -0.5])
vector2 = vector2 / np.linalg.norm(vector2)
a, b, c = vector1
x, y, z = vector2
def angle(b, c, z):
return np.arccos(z / np.sqrt(b ** 2 + c ** 2)) - np.arctan2(-b, c)
x_angle = angle(b, c, z)
x_after_x_rotation = a
y_after_x_rotation = b * np.cos(x_angle) - c * np.sin(x_angle)
det = np.sqrt(x_after_x_rotation ** 2 + y_after_x_rotation ** 2)
sin = x_after_x_rotation * y - y_after_x_rotation * x
cos = y_after_x_rotation * y + x_after_x_rotation * x
sin /= det
cos /= det
z_angle = np.arctan2(sin, cos)
print(np.rad2deg(x_angle), np.rad2deg(z_angle))
# 60.50379150343357 45.0
https://stackoverflow.com/questions/62016425
复制相似问题