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