将点旋转为与方向向量平行会传递错误的向量。为什么?

时间:2019-06-20 09:56:28

标签: python numpy vector rotation

我将需要旋转一个矢量,该矢量由其(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相同的方向。

https://math.stackexchange.com/questions/734707/how-to-rotate-a-3d-vector-to-be-parallel-to-another-3d-vector-using-quaternions/735136#735136

我已经设法实现了这一目标,尽管通过直观地显示结果,很明显它们不是平行的。

## 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

结果在这里:

visualization of the 3 vectors

如上所述,我希望橙色和绿色向量都是平行的,但不是。我缺少步骤了吗?

1 个答案:

答案 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