Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Euler angles to quaternion for rotations, please help

Author
Message
meehigh
16
Years of Service
User Offline
Joined: 29th Dec 2007
Location:
Posted: 29th Dec 2007 19:56
Hi. I am working on a project for school about solving Rubik's Cube, and I really need global rotations to visualize the face turns.
I searched an entire day for information on the web about Euler angles , matrices and quaternions, and I found everything I was looking for. I wrote all the functions that should transform the Euler angles of an object to a quaternion, cross product with a second quaternion to rotate around one of the axis, and then convert the resulting quaternion back to Euler angles and finally rotate the object correspondingly. And now... the results are not what I expected...
It would be so hard to redo the math, and try to figure out where the problem in the code is. So, I beg you, anyone out there, please, if you have written such code, or programmed something similar, please, just take a look at my code below and tell me what am I doing wrong.
I am just so tired. I've been trying to figure out Euler angles by myself for 2 days, and wrote (by hand) 8 pages of tables of all possible orientations of an object and tried to figure out this way on what axis should I perform a rotation if I want to rotate the object on a specific axis... and, of course, after more than a dozen tests, it didn't work... I really tried everything! Please, please help me! (I know EZrotate would be just what I need, but I am so close now to the answer... I just need a little help)
CattleRustler
Retired Moderator
21
Years of Service
User Offline
Joined: 8th Aug 2003
Location: case modding at overclock.net
Posted: 29th Dec 2007 20:08
deleted double post of same thread

My DBP plugins page is now hosted [href]here[/href]
Woozl
16
Years of Service
User Offline
Joined: 21st Dec 2007
Location:
Posted: 29th Dec 2007 20:23
Hello meehigh,

There is a pretty good discussion of Euler Angles vs Quaternions, and rotation in 3D space at this link:

http://wiki.secondlife.com/wiki/Rotation

It's pretty specific to SecondLife, but you may be able to gleen some useful info from it.

Regards,
Woozl
meehigh
16
Years of Service
User Offline
Joined: 29th Dec 2007
Location:
Posted: 29th Dec 2007 20:41

struct eulr_angls
{
float X, Y, Z;
};

struct quaternion
{
float w, x, y, z;
};

quaternion CrossProduct(quaternion q1, quaternion q2)
{
quaternion r;
r.w = q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z;
r.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y;
r.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z;
r.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x;

return r;
}

quaternion CreateAxisRotationQuaternion( float fTheta, float fX, float fY, float fZ )
{
quaternion q;
q.w = dbCOS( fTheta / 2 );
q.x = dbSIN( fTheta / 2 ) * fX;
q.y = dbSIN( fTheta / 2 ) * fY;
q.z = dbSIN( fTheta / 2 ) * fZ;

return q;
}

quaternion ConvertEulerAnglesToQuaternion( float fX, float fY, float fZ )
{
// Create the quaternions for pitch, turn, roll
quaternion p, t, r;
p = CreateAxisRotationQuaternion( fX, 1, 0, 0 );
t = CreateAxisRotationQuaternion( fY, 0, 1, 0 );
r = CreateAxisRotationQuaternion( fZ, 0, 0, 1 );

quaternion q;
q = CrossProduct( p, t );
q = CrossProduct( q, r );

return q;
}

eulr_angls ConvertQuaternionToEulerAngles( quaternion q )
{
int PI = 3.14159265359;

float r00, r01, r02;
float r10, r11, r12;
float r20, r21, r22;

r00 = 1 - 2 * q.y * q.y - 2 * q.z * q.z;
r01 = 2 * q.x * q.y + 2 * q.w * q.z;
r02 = 2 * q.x * q.z - 2 * q.w * q.y;

r10 = 2 * q.x * q.y - 2 * q.w * q.z;
r11 = 1 - 2 * q.x * q.x - 2 * q.z * q.z;
r12 = 2 * q.y * q.z + 2 * q.w * q.x;

r20 = 2 * q.x * q.z + 2 * q.w * q.y;
r21 = 2 * q.y * q.z - 2 * q.w * q.x;
r22 = 1 - 2 * q.x * q.x - 2 * q.y * q.y;

float thetaX, thetaY, thetaZ;

if (r02 < +1)
{
if (r02 > -1)
{
thetaY = asin(r02);
thetaX = atan2(-r12,r22);
thetaZ = atan2(-r01,r00);
}
else // r02 = -1
{
// Not a unique solution: thetaZ - thetaX = atan2(r10,r11)
thetaY = -PI/2;
thetaX = -atan2(r10,r11);
thetaZ = 0;
}
}
else // r02 = +1
{
// Not a unique solution: thetaZ + thetaX = atan2(r10,r11)
thetaY = PI;
thetaX = atan2(r10,r11);
thetaZ = 0;
}

eulr_angls EulerAngles;
EulerAngles.X = 180 / PI * thetaX;
EulerAngles.Y = 180 / PI * thetaY;
EulerAngles.Z = 180 / PI * thetaZ;

return EulerAngles;
}

//convert euler angles to quaternion q1
//create X axis rotation quaternion q2
//cross product q1 and q2: r = q1 * q2
//convert quaternion r to euler angles
//rotate the object using the euler angles

void dbInertialXRotateObject( int iObject, float fX )
{

}

void dbInertialYRotateObject( int iObject, float fY )
{
quaternion q1, q2, r;
q1 = ConvertEulerAnglesToQuaternion( dbObjectAngleX(iObject), dbObjectAngleY(iObject),dbObjectAngleZ(iObject) );
q2 = CreateAxisRotationQuaternion( 1, 0, 1, 0 );
r = CrossProduct( q1, q2 );

eulr_angls EulerAngles;
EulerAngles = ConvertQuaternionToEulerAngles( r );
dbRotateObject( iObject, EulerAngles.X, EulerAngles.Y, EulerAngles.Z );
}

void dbInertialZRotateObject( int iObject, float fZ )
{

}

Login to post a reply

Server time is: 2024-09-29 07:33:59
Your offset time is: 2024-09-29 07:33:59