如何找到从一个向量到另一个向量的正确旋转?

Tom*_*Tom 6 c++ opengl rotation quaternions

我有两个对象,每个对象有两个向量:

  • 法线向量
  • 向上矢量

就像这张图片:

在此处输入图片说明

向上向量垂直于法向量。现在我想找到从一个对象到另一个对象的唯一旋转,该怎么做?

我有一种方法可以找到一个向量到另一个向量之间的旋转,并且它有效。问题是我需要注意两个向量:法向量和向上向量。如果我使用此方法将法线向量从对象 1 旋转到对象 2 的法线,则向上向量可能指向错误的方向,并且它们需要平行。

这是查找最短旋转的代码:

GE::Quat GE::Quat::fromTo(const Vector3 &v1, const Vector3 &v2)
{
    Vector3 a = Vector3::cross(v1, v2);
    Quat q;

    float dot = Vector3::dot(v1, v2);

    if ( dot >= 1 ) 
    {
        q = Quat(0,0,0,1);

    }
    else if ( dot < -0.999999 )
    {
        Vector3 axis = Vector3::cross(Vector3(1,0,0),v2);

        if (axis.length() == 0) // pick another if colinear
                axis = Vector3::cross(Vector3(0,1,0),v2);
        axis.normalize();
        q = Quat::axisToQuat(axis,180);
    }
    else
    {
        float s = sqrt( (1+dot)*2 );
        float invs = 1 / s;

        Vector3 c = Vector3::cross(v1, v2);

        q.x = c.x * invs;
        q.y = c.y * invs;
        q.z = c.z * invs;
        q.w = s * 0.5f;
    }
    q.normalize();
    return q;
}
Run Code Online (Sandbox Code Playgroud)

我应该更改/添加什么到此代码,以找到正确的旋转?

Ama*_*eus 7

在我们开始之前,我将假设 UP 向量和法线向量在它们之间被归一化正交(点积为零)。

假设您想旋转黄色盘子以与玫瑰(红色?)盘子对齐。因此,我们的参考将是来自黄板的向量,我们将坐标系称为 XYZ,其中 Z -> 正常黄色向量,Y -> 向上黄色向量和 X -> YxZ(叉积)。

同样,对于玫瑰盘,旋转后的坐标系将称为 X'Y'Z',其中 Z' -> 正常玫瑰向量,Y' -> 向上玫瑰向量和 X' -> Y'xZ'(叉积)。

找到旋转矩阵,我们只需要确保我们正常的黄色向量会变成正常的玫瑰向量;我们的向上黄色向量将转换为向上玫瑰向量,依此类推,即:

RyellowTOrose = |X'x   Y'x   Z'x|
                |X'y   Y'y   Z'y|
                |X'z   Y'z   Z'z|
Run Code Online (Sandbox Code Playgroud)

换句话说,在您将任何图元转换为黄色坐标系后,应用此转换,将旋转它以与玫瑰坐标系对齐

如果您的向上和法向矢量不正交,您可以轻松地纠正其中之一。只需在 normal 和 up 之间做叉积(为了方便起见,得到一个称为 C 的向量),然后再次在 C 和 normal 之间做叉积,以纠正 up 向量。