四元数基变换

时间:2013-04-22 12:45:55

标签: c++ rotation quaternions

我有一个四元数,基于Y轴向上的坐标系,X轴在右边,Z轴在我看来。

现在我想基于这个四元数在另一个应用程序(C ++)中移动一个字符。如果坐标系相同,但这个应用程序使用不同的坐标系,这将没有问题。 Z向上,X向右,Y通过监视器(向内)。

我试着简单地旋转四元数来调整坐标系,但是我试过的每次旋转都看起来都不正确。

我的想法是我需要某种基本转换,但我不知道如何使用四元数来做这个,有没有人知道如何在四元数上执行基本转换?

修改

我使用Eigen C ++ lib进行Quaternions。这是我使用的四元数:

Quaternion<float> QX90( Eigen::AngleAxisf( M_PI /2.0, Eigen::Vector3f::UnitX() ) );
Quaternion<float> nQX90( Eigen::AngleAxisf( -M_PI /2.0, Eigen::Vector3f::UnitX() ) );

Quaternion<float> Qrshoulder = .... //the Quaternion in the Y up coordinate system

我尝试旋转X轴:

Qrshoulder=Qrshoulder*QX90; 
Qrshoulder=QX90*Qrshoulder;
Qrshoulder=Qrshoulder*nQX90;
Qrshoulder=nQX90*Qrshoulder;

这没有用。我还尝试了其他几个乘法,我几乎尝试了每一个似乎合乎逻辑的旋转。我很困惑..这似乎不能用四元数乘法

来完成

编辑2

我有绝对和分层的四元数。 Hierarchical Quaternions提供从父骨骼到子骨骼的3D空间中的旋转量。绝对四元数是相乘的层次骨骼方向。

另一方面,我想要制作动画的角色后面有一个引擎,它已经将骨骼倍增,所以我肯定需要使用分层旋转。但问题是,当我使用分层旋转时,Y轴总是位于骨骼的方向上。

我从Nolnoch的回答中尝试了什么:

Quaternion<float> QNX( Eigen::AngleAxisf( 0, Eigen::Vector3f(1,0,0) ) );

rot=(QNX*QX90*Qrshoulder).toRotationMatrix();
targetNode->setRotation( Eigen::Transform3f( rot ) );

这对于hierarchycal或绝对方向都没有用。这篇文章描述了我得到的四元数:http://msdn.microsoft.com/en-us/library/hh973073.aspx

我想我想念的是,当使用分层方向时,我得到了我需要的正确旋转量,但是由于Y轴沿着骨骼,而且在我的collada中,坐标系统完全混乱了系统始终是Z向上。我不知道如何改变这一点,我甚至不确定这是不是我的问题。

1 个答案:

答案 0 :(得分:2)

你能展示你尝试过的旋转吗?听起来你的次要基础是在负X轴旋转90度后的原始基础。

您可以使用四元数[w,x,y,z] = [cos(PI / 4),sin(PI / 4),0,0]基于角度轴向量[(PI / 2),1,0,0]。您还可以将原始四元数转换为矩阵形式,并连接仿射旋转矩阵。我现在忘记了sin / cos术语的顺序。

还要注意你的矢量和矩阵的乘法顺序。 (v'= Rv)!=(v'= vR)。

[编辑1]
问题是,四元数没有固有的手性或对特定基础的依恋。它们只是关于参照原点定义的方向分量的一定量的运动。此外,它们不存储有关先前轮换的明确信息。

因此,在一个上下文中围绕Z轴旋转35度的表示的最终四元数仍将围绕另一个中的Z轴旋转35度。由于你的第二个基础是离你的原始基础旋转大约X,这应该有效。

需要考虑的其他事项:

你提到一个肩膀 - 这是一个层次结构吗?如果是这样,这个特定的四元数是该肢体的真正最终/全局四元数,还是它引用另一个本地上下文(并被连接)?

您在其他应用程序中实现此四元数的上下文是什么?如果它是相同的层次结构,尝试在开始递归渲染之前通过此校正四元数转换ModelView,然后在完成后转换回(或使用矩阵堆栈)。

[编辑2]
什么是QNX?您可以定义没有关联运动的轴。如果您尝试使用零或“空”四元数,则它是[w,x,y,z] = [1,0,0,0]。

除非在库的实现中进行修改,否则四元数乘法是从右(基本旋转)到左(新旋转)。我查看了Eigen,并没有提到在文档中切换内容。

此外,每次旋转都会将全局轴与对象一起变换,因此如上所述,在渲染层次模型之前,应将此校正四元数(QX90)添加到全局绝对旋转中。见下文。

Identity Matrix (clean slate)             Rotations in effect: [ ]
  Rotation 1                                                   [1]
    Draw some object                                           [1]

Identity Matrix                                                [ ]
  Rotation Q (QX90)                                            [Q]
    Rotation A (hip)                                           [A*Q]
      Draw hip                                                 [A*Q]
      Rotation B (spine)                                       [B*A*Q]
        Draw spine                                             [B*A*Q]
        Rotation C (shoulder)                                  [C*B*A*Q]
          Draw shoulder                                        [C*B*A*Q]

我只是递归地呈现层次模型,而不是您发布的MSDN指南的迭代结构。不过,这是关于其旋转分量的全局变换矩阵的状态背后的想法。