旋转一个点使其与方向矢量平行会产生错误的矢量。为什么?

Rotating a point to be parallel to a direction vector delivers wrong vector. Why?

我需要旋转一个矢量,该矢量的起点为 (0,0,0),终点为给定点,以便与给定的方向矢量平行。出于这个原因,我的代码基于以下答案:

I guess by "parallel" you intend "pointing in the same direction."

We may as well rotate (d,e,f) in the plane spanned by v=(d,e,f) and w=(a,b,c). The axis of rotation >would be around a vector perpendicular to this plane such as a=v×w, which >you'd normalize to a unit length vector u. Finally, we'd need the angle of >rotation θ, which can be retrieved from v⋅w=∥v∥∥w∥cos(θ) by solving for θ.

Then following the scheme for using quaternions to perform rotations, the >quaternion you're looking for is q=cos(θ/2)+usin(θ/2). The transformation >x→qxq−1 moves v to point in the same direction as 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

这里是结果:

如前所述,我希望橙色和绿色矢量是平行的,但它们不是。有没有我遗漏的步骤?

所以经过一些修改我设法得到了想要的输出。我从 .

得到了乘法函数
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