I'm trying to convert quaternions to euler (and viceversa) using equations, one of our project doesn't uses ogre, so we can't use its functions.
Currently i've these two equations from this page:
QtE: http://www.euclideanspace.com/maths/geo ... /index.htm
EtQ: http://www.euclideanspace.com/maths/geo ... /index.htm
Standards: http://www.euclideanspace.com/maths/standards/index.htm
My implementation is:
Code: Select all
//http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/index.htm
public void FromEulerAngles(float eulerX, float eulerY, float eulerZ)
{
// Assuming the angles are in radians.
double c1 = System.Math.Cos(eulerY / 2);
double s1 = System.Math.Sin(eulerY / 2);
double c2 = System.Math.Cos(eulerZ / 2);
double s2 = System.Math.Sin(eulerZ / 2);
double c3 = System.Math.Cos(eulerX / 2);
double s3 = System.Math.Sin(eulerX / 2);
double c1c2 = c1 * c2;
double s1s2 = s1 * s2;
W = (float)(c1c2 * c3 - s1s2 * s3);
X = (float)(c1c2 * s3 + s1s2 * c3);
Y = (float)(s1 * c2 * c3 + c1 * s2 * s3);
Z = (float)(c1 * s2 * c3 - s1 * c2 * s3);
}
//http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm
public Vector3 ToEulerAngles()
{
Debug.Assert(IsNormalized(), "This formula assumes that the quaternion is normalized...");
Vector3 p = new Vector3();
float x = X, y = Y, z = Z, w = W;
double test = x * y + z * w;
if (test > 0.499)
{ // singularity at north pole
p.Y = (float)(2.0 * System.Math.Atan2(x, w));
p.Z = (float)(System.Math.PI / 2.0);
p.X = 0;
}
else if (test < -0.499)
{ // singularity at south pole
p.Y = (float)(-2.0 * System.Math.Atan2(x, w));
p.Z = (float)(-System.Math.PI / 2.0);
p.X = 0;
}
else
{
double sqx = x * x;
double sqy = y * y;
double sqz = z * z;
p.Y = (float)System.Math.Atan2(2 * y * w - 2 * x * z, 1 - 2 * sqy - 2 * sqz);
p.Z = (float)System.Math.Asin(2 * test);
p.X = (float)System.Math.Atan2(2 * x * w - 2 * y * z, 1 - 2 * sqx - 2 * sqz);
}
return p;
}
Code: Select all
public void TestEuler(Vector3 expectedEuler)
{
Quaternion convertedQuaternion = new Quaternion();
convertedQuaternion.FromEulerAngles(expectedEuler);
Vector3 reconvertedEuler = convertedQuaternion.ToEulerAngles();
Assert.AreEqual(expectedEuler.X, reconvertedEuler.X, expectedEuler.X * 0.00001f, "Quaternion Euler conversion failed in component X");
Assert.AreEqual(expectedEuler.Y, reconvertedEuler.Y, expectedEuler.Y * 0.00001f, "Quaternion Euler conversion failed in component Y");
Assert.AreEqual(expectedEuler.Z, reconvertedEuler.Z, expectedEuler.Z * 0.00001f, "Quaternion Euler conversion failed in component Z");
}
[TestMethod()]
public void TestQuaternions()
{
TestEuler(new Vector3(0, (float)Math.PI, (float)Math.PI / 2.0f));
TestEuler(new Vector3(0.5489f, 1.5475f, 2.6845f));
}
expectedEuler {(0,5489, 1,5475, 2,6845)}
reconvertedEuler {(-2,592693, -1,594092, 0,4570926)}
I've no idea of what i'm doing wrong...
Thanks in advance!
