我正在使用SharpDX编写一个相机,并借助四元数进行旋转。
- 相机旋转由俯仰(X轴旋转)、偏航(Y轴旋转)和滚转(Z轴旋转)设置,这被称为“Tiat-Bryan”角(这不是欧拉角,欧拉角具有XYX旋转,而不是XYZ)。
- 我使用的是左手坐标系:X+向右,Y+向上,Z+向下屏幕。
- 如果我绕X轴旋转(“俯仰”),正值使相机看向下方。如果我绕Y轴旋转(“偏航”),正值使相机看向左侧。如果我绕Z轴旋转(“翻滚”),相机会顺时针翻滚。
我已经能够从四元数中获取俯仰、偏航和滚转,以下是C#代码:
public static class QuaternionExtensions
{
public static Vector3 GetPitchYawRoll(this Quaternion q)
{
return new Vector3(q.GetPitch(), q.GetYaw(), q.GetRoll());
}
public static float GetPitch(this Quaternion q)
{
return q.GetK().GetPitch();
}
public static float GetYaw(this Quaternion q)
{
return q.GetK().GetYaw();
}
public static float GetRoll(this Quaternion q)
{
// This is M12 * M22 of rotation matrix
float xx = q.X * q.X;
float xy = q.X * q.Y;
float zz = q.Z * q.Z;
float wz = q.W * q.Z;
return (float)Math.Atan2(2f * (xy - wz), 1f - 2f * (xx + zz));
}
public static Vector3 GetK(this Quaternion q)
{
float xz = q.X * q.Z;
float wy = q.W * q.Y;
float yz = q.Y * q.Z;
float wx = q.W * q.X;
float xx = q.X * q.X;
float yy = q.Y * q.Y;
return new Vector3(
2f * (xz - wy),
2f * (yz + wx),
1f - 2f * (xx + yy));
}
}
public static class Vector3Extensions
{
public static float GetPitch(this Vector3 v)
{
return (float)-Math.Atan2(v.Y, Math.Sqrt(v.X * v.X + v.Z * v.Z));
}
public static float GetYaw(this Vector3 v)
{
return (float)-Math.Atan2(v.X, v.Z);
}
}
我不知道另一种方法。如何通过指定俯仰角、偏航角和滚动角来获取四元数(例如从GetPitchYawRoll
返回的向量3中返回的内容)?
v.Y
)中减去*/2*,使其在0处水平。这几乎肯定是由于Tait-Bryan角和更正式的欧拉角之间存在轻微差异所致。 - Warpspace