本文介绍了从Tait-Bryan角度的四元数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用SharpDX编写相机,并在四元数的帮助下旋转相机。
I am writing a camera with SharpDX and rotate it with the help of a quaternion.
- 相机旋转设置为pitch X旋转),偏航(Y旋转)和滚动(Z旋转),因此称为Tiat-Bryan角度(这些不欧拉角,其将具有XYX旋转,而不是XYZ) / li>
- 我使用的是左手坐标系:X +向右,Y +向上,Z +向下。
- (俯仰),正值使相机向下看。如果我绕Y旋转(偏航),正值使相机向左看。如果我绕Z旋转(滚动),相机顺时针旋转。
- The camera rotation is set with pitch (X rotation), yaw (Y rotation) and roll (Z rotation), so called "Tiat-Bryan" angles (these are not Euler angles which would have an XYX rotation, and not XYZ).
- I am using a left-handed coordinate system: X+ is rightwards, Y+ is upwards, Z+ is downwards the screen.
- If I rotate around X ("pitching"), positive values make the camera look downwards. If I rotate around Y ("yawing"), positive values make the camera look leftwards. If I rotate around Z ("rolling"), the camera rolls clockwise.
我已经能够获得俯仰,从四元数。以下C#代码:
I was already able to get pitch, yaw and roll from the quaternion, s. the following C# code:
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
中返回的内容)?
I don't know the other way round. How to get the quaternion by specifying pitch, yaw and roll (e.g. what's returned in the Vector3 from GetPitchYawRoll
)?
推荐答案
来自BlitzBasic.com论坛的Kryzon帮助我在这里(s。他的帖子):
Kryzon from the BlitzBasic.com forum helped me out here (s. his post at http://blitzbasic.com/Community/post.php?topic=102458&post=1224801):
internal static class QuaternionExtensions
{
internal static Vector3 GetYawPitchRollVector(this Quaternion q)
{
return new Vector3(q.GetYaw(), q.GetPitch(), q.GetRoll());
}
private static float GetYaw(this Quaternion q)
{
float x2 = q.X * q.X;
float y2 = q.Y * q.Y;
return (float)Math.Atan2(2f * q.Y * q.W - 2f * q.Z * q.X, 1f - 2f * y2 - 2f * x2);
}
private static float GetPitch(this Quaternion q)
{
return (float)-Math.Asin(2f * q.Z * q.Y + 2f * q.X * q.W);
}
private static float GetRoll(this Quaternion q)
{
float x2 = q.X * q.X;
float z2 = q.Z * q.Z;
return (float)-Math.Atan2(2f * q.Z * q.W - 2f * q.Y * q.X, 1f - 2f * z2 - 2f * x2);
}
}
internal static class Vector3Extensions
{
internal static Quaternion GetYawPitchRollQuaternion(this Vector3 v)
{
float c1 = (float)Math.Cos(-v.Z / 2.0);
float c2 = (float)Math.Cos(-v.Y / 2.0);
float c3 = (float)Math.Cos( v.X / 2.0);
float c1c2 = c1 * c2;
float s1 = (float)Math.Sin(-v.Z / 2.0);
float s2 = (float)Math.Sin(-v.Y / 2.0);
float s3 = (float)Math.Sin( v.X / 2.0);
float s1s2 = s1 * s2;
return new Quaternion(
c1 * s2 * c3 - s1 * c2 * s3,
c1c2 * s3 + s1s2 * c3,
s1 * c2 * c3 + c1 * s2 * s3,
c1c2 * c3 - s1s2 * s3);
}
}
这篇关于从Tait-Bryan角度的四元数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!