Is there an algorithm for converting quaternion rotations to Euler angle rotations?

前端 未结 8 1630
臣服心动
臣服心动 2020-12-12 13:35

Is there an existing algorithm for converting a quaternion representation of a rotation to an Euler angle representation? The rotation order for the Euler representation is

8条回答
  •  既然无缘
    2020-12-12 14:19

    In a right-handed Cartesian coordinate system with Z axis pointing up, do this:

    struct Quaternion
    {
        double w, x, y, z;
    };
    
    void GetEulerAngles(Quaternion q, double& yaw, double& pitch, double& roll)
    {
        const double w2 = q.w*q.w;
        const double x2 = q.x*q.x;
        const double y2 = q.y*q.y;
        const double z2 = q.z*q.z;
        const double unitLength = w2 + x2 + y2 + z2;    // Normalised == 1, otherwise correction divisor.
        const double abcd = q.w*q.x + q.y*q.z;
        const double eps = 1e-7;    // TODO: pick from your math lib instead of hardcoding.
        const double pi = 3.14159265358979323846;   // TODO: pick from your math lib instead of hardcoding.
        if (abcd > (0.5-eps)*unitLength)
        {
            yaw = 2 * atan2(q.y, q.w);
            pitch = pi;
            roll = 0;
        }
        else if (abcd < (-0.5+eps)*unitLength)
        {
            yaw = -2 * ::atan2(q.y, q.w);
            pitch = -pi;
            roll = 0;
        }
        else
        {
            const double adbc = q.w*q.z - q.x*q.y;
            const double acbd = q.w*q.y - q.x*q.z;
            yaw = ::atan2(2*adbc, 1 - 2*(z2+x2));
            pitch = ::asin(2*abcd/unitLength);
            roll = ::atan2(2*acbd, 1 - 2*(y2+x2));
        }
    }
    

提交回复
热议问题