来自Tait的Quaternion

我正在用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中Vector3中返回的是什么)?


    来自BlitzBasic.com论坛的Kryzon帮助我在这里(他的帖子在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);
        }
    }
    

    这一切都被称为欧拉角,

    http://en.wikipedia.org/wiki/Euler_angles

    转换的所有变体可以在http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/ Ken Shoemake,1993

    链接地址: http://www.djcxy.com/p/81779.html

    上一篇: Quaternion from Tait

    下一篇: Adding an euler angle to a Quaternion