/// <summary>
        /// Converts a quaternion to a euler angle.
        /// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
        /// </summary>
        /// <param name="quaternion">The quaternion to convert from.</param>
        /// <returns>An euler angle.</returns>
        public static FixVec3 ToEuler(FixQuaternion quaternion)
        {
            FixVec3 result;

            Fix t0 = 2 * (quaternion.w * quaternion.z + quaternion.x * quaternion.y);
            Fix t1 = Fix.one - (2 * (quaternion.y * quaternion.y + quaternion.z * quaternion.z));

            result.z = FixMath.Atan2(t0, t1);

            Fix t2 = 2 * (quaternion.w * quaternion.y - quaternion.z * quaternion.x);

            if (t2 >= Fix.one)
            {
                result.y = FixMath.PI / 2;
            }
            else if (t2 <= -Fix.one)
            {
                result.y = -(FixMath.PI / 2);
            }
            else
            {
                result.y = FixMath.Asin(t2);
            }

            Fix t3 = 2 * (quaternion.w * quaternion.x + quaternion.y * quaternion.z);
            Fix t4 = Fix.one - (2 * (quaternion.x * quaternion.x + quaternion.y * quaternion.y));

            result.x = FixMath.Atan2(t3, t4);
            return(result);
        }
Example #2
0
        public void AsinAverageDeviationTest()
        {
            var totalDiff = 0.0;
            var maxDiff   = double.MinValue;

            for (var i = 0; i < 1000; i++)
            {
                var fixValue    = Fix.Ratio(i, 1000);
                var doubleValue = i / 1000.0;

                var diff = Math.Abs((double)FixMath.Asin(fixValue) - Math.Asin(doubleValue));
                totalDiff += diff;
                maxDiff    = Math.Max(maxDiff, Math.Abs(diff));
            }
            // Max & Average deviation
            FixAssert.AssertEquals(maxDiff, 0, 0.005f);
            FixAssert.AssertEquals(totalDiff / 360, 0, 0.002f);
        }