C++ 四元数-旋转到

C++ 四元数-旋转到,c++,math,quaternions,C++,Math,Quaternions,我在世界空间中有一个物体,比如说在(0,0,0)处,想将它旋转到面(10,10,10) 如何使用四元数进行此操作?您可能需要使用SLERP(球面线性插值)。有关如何在c++中执行此操作的参考,请参见此。计算表示两个向量之间旋转的四元数的示例可以在的OGRE源代码中找到。响应您的说明并回答此问题,我已经无耻地复制了一个非常有趣和简洁的算法来寻找两个向量之间的quat,这看起来是我以前从没有见过的。从数学上讲,它似乎是有效的,因为你的问题是关于它背后的数学,我相信你能把这个伪代码转换成C++。 qu

我在世界空间中有一个物体,比如说在(0,0,0)处,想将它旋转到面(10,10,10)


如何使用四元数进行此操作?

您可能需要使用SLERP(球面线性插值)。有关如何在c++中执行此操作的参考,请参见此。

计算表示两个向量之间旋转的四元数的示例可以在的OGRE源代码中找到。

响应您的说明并回答此问题,我已经无耻地复制了一个非常有趣和简洁的算法来寻找两个向量之间的quat,这看起来是我以前从没有见过的。从数学上讲,它似乎是有效的,因为你的问题是关于它背后的数学,我相信你能把这个伪代码转换成C++。
quaternion q;
vector3 c = cross(v1,v2);
q.v = c;
if ( vectors are known to be unit length ) {
    q.w = 1 + dot(v1,v2);
} else {
    q.w = sqrt(v1.length_squared() * v2.length_squared()) + dot(v1,v2);
}
q.normalize();
return q;
如果您需要帮助澄清伪代码的任何部分,请告诉我。不过应该是直截了当的

dot(a,b) = a1*b1 + a2*b2 + ... + an*bn


这个问题没有什么意义。您说过希望对象“面向”特定点,但这并没有提供足够的信息

首先,面对这个方向意味着什么?在OpenGL中,这意味着本地参考帧中的-z轴与某些外部参考帧中的指定方向对齐。为了实现这种对齐,我们需要知道对象的相关轴当前“面向”的方向

然而,这仍然不能定义唯一的转换。即使您知道使-z轴指向哪个方向,对象仍然可以围绕该轴自由旋转。这就是函数
gluLookAt()
要求提供“at”方向和“up”方向的原因

我们需要知道的下一件事是最终结果需要采用什么格式?对象的方向通常以四元数格式存储。但是,如果要以图形方式旋转对象,则可能需要旋转矩阵

让我们做一些假设。我假设您的对象以世界点c为中心,并具有默认对齐方式。即,对象的xyz轴与世界的xyz轴对齐。这意味着对象相对于世界的方向可以表示为单位矩阵或单位四元数:
[1 0 0 0]
(使用四元数约定,其中w优先)

如果要使对象的-z轴与点p:=[p.x p.y p.z]对齐的最短旋转,则将围绕轴a旋转φ。现在我们将找到这些值。首先,我们通过规范化向量p-c找到轴a,然后取单位长度-z向量的叉积,然后再次规范化:

a=标准化(交叉积(-z,标准化(p-c))

这两个单位向量之间的最短角度,取其点积的反余弦:

φ=acos(点积(-z,归一化(p-c))

不幸的是,这是两个向量形成的角度的绝对值的度量。我们需要弄清楚当围绕a旋转时,它是正的还是负的。必须有一种更优雅的方法,但我想到的第一种方法是找到第三个轴,垂直于a-z,然后从它的点积和目标轴上取符号。可视信息:

b=交叉积(a-z


如果(点积(b,标准化(p-c)你是不是在问四元数旋转背后的数学问题,或者是如何实现它?如果你理解四元数是如何工作的,在C++中实现它们是非常简单的,并且取决于这是不是一次性的事情,可以用几行代码来完成。如果你不理解四元数,这是错误的。place@AK4749-嗨,我在问ab这里有两个向量3,其中(1)是对象的位置,(2)是我希望该对象旋转到的位置-我如何计算表示该旋转的四元数?四元数擅长在矩阵而不是向量之间插值。至少需要两组两个向量(位置+方向)构建两个矩阵(即位置+旋转)。然后将这些矩阵转换为四元数,对它们进行插值,然后再转换回矩阵。@user1654209这只是有用的一半。虽然我个人认为四元数比欧拉角更适合于同质变换等,但你不需要按照你所说的方法来推导出一个四元数会产生一个给定的结果。谢谢,但我不需要维基百科上的四元数课程:)我担心的是你觉得我的评论有一半用处,我只是想知道为什么。非常感谢你的精彩解释谢谢你的解释。我的问题已经解决了,感谢你的描述和JCooper的解释。
cross(a,b) = well, the cross product. it's annoying to type out and
can be found anywhere.