我想为现有的四元数添加一个euler角度。这是我得到的:
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) 。这里的问题是,当我从四元数中提取欧拉角时,我也会得到万向节锁。
那么如何将特定轴的euler角度添加到四元数?
答案 0 :(得分: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_w 和 y_w 的旋转。如果已经将任何偏航应用于转换,则 x_o 不再与 x_w 对齐;因此,你会得到一些 roll 。幸运的是,对于你正在应用的变换,万向节锁定不是问题。如果你投球 90度, yaw 和 roll 就会变成同样的事情。但是你没有使用 roll ;所以没关系。
您的变换总是可以表示为围绕 x_w 的旋转,然后围绕 y_w 进行旋转。将新的“音高四元数”放在旧变换的左侧会将其添加到其他累积的音高。保持右侧的“偏航四元数”将其添加到累积的偏航。因此,如果您要将最终四元数表示为一堆或乘法,那么它将围绕 x_w 进行一系列纯旋转,然后围绕 y_w 进行一系列旋转。只要对象以 x_o 平行于 x_w 开始,就可以实现所需。