Quaternion from Tait-Bryan angles

核能气质少年 提交于 2019-12-04 13:29:46

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);
    }
}
minorlogic

This all often called Euler Angles,

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

All variants of conversion can be found at https://github.com/erich666/GraphicsGems/blob/master/gemsiv/euler_angle/EulerAngles.c

Originally written by Ken Shoemake, 1993

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!