9

我想为现有的四元数添加欧拉角。这是我得到的:

Quaternion oldTransform = transform.Rotation;

float YawRotation = mouseDiff.x *  RotationSpeed;
Quaternion YawRotationQuaternion = new Quaternion();
YawRotationQuaternion.CreateFromAxisAngle (0, 1, 0, YawRotation);

float PitchRotation = mouseDiff.y * RotationSpeed;
Quaternion PitchRotationQuaternion = new Quaternion();
PitchRotationQuaternion.CreateFromAxisAngle ( 1, 0, 0, PitchRotation);

Quaternion result = oldTransform * YawRotationQuaternion * PitchRotationQuaternion;
transform.Rotation = result;

我只想有偏航和俯仰旋转。旧变换具有此属性。我添加的欧拉角也只是俯仰和偏航旋转。当我乘以它时会发生什么,oldTransform 描述的旋转引入了滚动旋转。

然后我尝试了:

Quaternion result = YawRotationQuaternion * oldTransform * PitchRotationQuaternion;

这不会引入滚动旋转。此选项更糟糕,因为当 oldTransform 将偏航轴旋转到俯仰轴上时,它具有万向节锁定。

现在我可以想象的是,人们从 oldTransform 获取旧的偏航和俯仰旋转并修改偏航和俯仰轴,使它们不再是 (0,1,0) 和 (1,0,0)。这里的问题是,当我从四元数中提取欧拉角时,我也会得到万向节锁。

那么如何将特定轴的欧拉角添加到四元数?

4

1 回答 1

5

解决方案:

更改转换的顺序。

Quaternion result = PitchRotationQuaternion * oldTransform * YawRotationQuaternion;

解释:

您有一个具有本地参考系的对象。我会说+x_o朝向对象的右侧,-z_o是“向前”,而+y_o是相对于对象“向上”。该对象存在于世界的参考系中。世界有它自己的轴:(x_w,y_w,z_w),其中+y_w是世界向上。当对象改变方向时,您希望它俯仰(围绕x_o旋转)和偏航(围绕y_w旋转)。

在您的代码中,您创建了两个四元数。应用它们的方式代表围绕x_wy_w的旋转。如果有任何偏航已经应用于转换,则x_o不再与x_w对齐;因此,你会得到一些roll。幸运的是,对于您正在应用的转换,万向节锁定不是问题。万向节锁定在这里可以通过以下事实来证明:如果您俯仰90 度,偏航滚动就变成了同一件事。但是您不使用roll;所以没关系。

您的变换始终可以表示为围绕 x_w 旋转,然后围绕y_w旋转。将新的“音高四元数”放在旧变换的左侧,将其添加到另一个累积音高中。保持右侧的“偏航四元数”会将其添加到累积偏航中。因此,如果您要将最终的四元数表示为一串或乘法,它将是围绕 x_w 的一串纯旋转,然后是围绕y_w一串旋转。只要对象以 x_o 与x_w平行开始,这就是你想要的。

于 2013-06-27T15:17:50.043 回答