我将需要旋转一个矢量,该矢量由其(0,0,0)处开始并在给定点处结束,以与给定方向矢量平行。因此,我的代码基于以下答案:
我猜想“平行”是指“指向同一方向”。
我们也可以旋转(d,e,f) 在由v =(d,e,f)和w =(a,b,c)跨越的平面中。旋转轴>将围绕垂直于该平面的向量,例如a = v×w,该向量>将归一化为单位长度向量u。最后,我们需要>旋转角度θ,可以通过求解θ从v⋅w=∥v∥∥w∥cos(θ)中检索出。
然后按照使用四元数执行旋转的方案,要查找的>四元数为q = cos(θ/ 2)+ usin(θ/ 2)。变换> x→qxq-1会使v指向与w相同的方向。
我已经设法实现了这一目标,尽管通过直观地显示结果,很明显它们不是平行的。
## Example code
def get_unit_vector(vector):
return vector / np.linalg.norm(vector)
def get_angle_between_vectors(vector1, vector2):
unit_vector_1 = get_unit_vector(vector1)
unit_vector_2 = get_unit_vector(vector2)
angle = np.arccos(np.dot(unit_vector_2, unit_vector_1))
return min(angle, np.pi-angle)
def rotate_point(point, direction):
# get the axis and normalize it
axis = np.cross(point, direction)
norm_axis = get_unit_vector(axis)
angle = get_angle_between_vectors(point, direction)
q = np.cos((angle/2))+norm_axis*np.sin(angle/2)
q = get_unit_vector(q)
new_point = (q*point)*np.conj(q)
new_angle = get_angle_between_vectors(new_point, direction)
if new_angle != 0:
q = np.cos((np.pi-angle / 2)) + norm_axis * np.sin(np.pi-angle / 2)
new_point = (q * point) * (np.conj(q))
return new_point
结果在这里:
如上所述,我希望橙色和绿色向量都是平行的,但不是。我缺少步骤了吗?
答案 0 :(得分:0)
因此,在进行一些修改之后,我设法获得了所需的输出。我从here得到了乘法函数。
def get_unit_vector(vector):
return vector / np.linalg.norm(vector)
def get_angle_between_vectors(vector1, vector2):
unit_vector_1 = get_unit_vector(vector1)
unit_vector_2 = get_unit_vector(vector2)
angle = np.arccos(np.dot(unit_vector_2, unit_vector_1))
return min(angle, np.pi-angle)
def quaternion_conjugate(q):
first = q[0]
q_prime = -1*q
q_prime[0] = first
return q_prime
def quaternion_multiply(quaternion1, quaternion0):
w0, x0, y0, z0 = quaternion0
w1, x1, y1, z1 = quaternion1
return np.array([-x1 * x0 - y1 * y0 - z1 * z0 + w1 * w0,
x1 * w0 + y1 * z0 - z1 * y0 + w1 * x0,
-x1 * z0 + y1 * w0 + z1 * x0 + w1 * y0,
x1 * y0 - y1 * x0 + z1 * w0 + w1 * z0], dtype=np.float64)
def rotate_point(point, direction):
axis = np.cross(point, direction)
norm_axis = get_unit_vector(axis)
angle = -get_angle_between_vectors(point, direction)
q = np.array([np.cos((angle/2)),*(norm_axis*np.sin(angle/2))])
point_as_q = np.array([0,*point])
q3 = quaternion_multiply(q, point_as_q)
q3 = quaternion_multiply(q3, quaternion_conjugate(q))
new_point = q3[1:]
return new_point