• 10
• 10
• 12
• 12
• 14

# Quaternion and Axis Angle

This topic is 4668 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi guys, I'm little confused with the Quaternion and Axis Angle. In GameTutorials.com's MD3 animation tutorial, they use Quaternion. I reuse the quaternion class from them, that's I make my own glRotate function(which is axis angle), then convert it to quaternion, then to matrix and applied it :
void CQuaternion::CreateMatrix(float *pMatrix)
{
//This is GameTutorials.com's
if(!pMatrix) return;
pMatrix[ 0] = 1.0f - 2.0f * ( y * y + z * z );
pMatrix[ 1] = 2.0f * ( x * y - w * z );
pMatrix[ 2] = 2.0f * ( x * z + w * y );
pMatrix[ 3] = 0.0f;
pMatrix[ 4] = 2.0f * ( x * y + w * z );
pMatrix[ 5] = 1.0f - 2.0f * ( x * x + z * z );
pMatrix[ 6] = 2.0f * ( y * z - w * x );
pMatrix[ 7] = 0.0f;
pMatrix[ 8] = 2.0f * ( x * z - w * y );
pMatrix[ 9] = 2.0f * ( y * z + w * x );
pMatrix[10] = 1.0f - 2.0f * ( x * x + y * y );
pMatrix[11] = 0.0f;
pMatrix[12] = 0;
pMatrix[13] = 0;
pMatrix[14] = 0;
pMatrix[15] = 1.0f;
}

void CQuaternion::MyRotate(float angle, float sb_x, float sb_y, float sb_z)
{
//This is my own glRotatef
rad = angle* PI / 180;
l=sqrt(w * w + x * x + y * y + z * z);
w/=l; x/=l; y/=l; z/=l;
CreateMatrix(m_now);
glMultMatrixf(m_now);
}


The problem is, when I switch between using OpenGL's glRotate and my own glRotate the object rotates to opposite direction !
int DrawGLScene(GLvoid)
{
CQuaternion k;
rtri=45;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef(0.0f ,0.f, -6.0f);

if(flag==true)
{
glTranslatef(1.5f,0.0f,0.0f);
glRotatef(rtri,0.0f,0.0f,1.0f);
}
else
{
glTranslatef(1.5f,0.0f,0.0f);
k.MyRotate(rtri, 0.0f, 0.0f, 1.0f);
}

glBegin(GL_TRIANGLES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f, 0.0f);
glColor3f(0.0f,0.0f,1.0f);
glVertex3f( 1.0f,-1.0f, 0.0f);
glEnd();
return TRUE;
}


BTW, I got Matrix and Quaternion FAQ from somewhere in the net before. It has formula to convert axis angle -> quaternion -> matrix(Q56 then Q54). What funny is, suppose I rotate 45 degree in Z axis, the matrix result for (axis angle -> quaternion -> matrix) is transpose of Z-axis rotation matrix(Q30). Thanks. [Edited by - EonStrife on July 9, 2005 7:08:55 PM]

##### Share on other sites
Quote:
 Original post by EonStrifeWhat funny is, suppose I rotate 45 degree in Z axis, the matrix result for (axis angle -> quaternion -> matrix) is transpose of Z-axis rotation matrix(Q30).

Because the math itself is funny ;) Did you know, that inversion of an orthonormal matrix is the same as its transposition? Rotation matrix is orthonormal.

Your result simply says that your angle is somewhat negated. That could happen, when you are calculating it with arcus cosine. Cosine is symmetric along Y axis, so the angle returned by acos is always > 0, cause there's nothing that the function could do to distinguish between angle and -angle. You probably want to have -angle.
That, of course, is not a general rule. It depends on what your routine of calculating angle is. Where does it come from? (I assumed you made dot and acos, but it could be otherwise).

Another possibility is that you are using OpenGL right-handed coordinates, and the original third-party snippet assumed it will work in left-handed. Sine would have been negated, resulting in reversed rotation.

This is my rotation code, for comparison:
// rotation matrixINL xmat rotation (cxquat & q) {   xmat m = identityMat();   ((float*)&m)[0] = 1.0f - (q.y*q.y + q.z*q.z)*2.0f; // 0,0   ((float*)&m)[4] = (q.x*q.y - q.w*q.z)*2.0f;        // 0,1   ((float*)&m)[8] = (q.x*q.z + q.w*q.y)*2.0f;        // 0,2   ((float*)&m)[1] = (q.x*q.y + q.w*q.z)*2.0f;        // 1,0   ((float*)&m)[5] = 1.0f - (q.x*q.x + q.z*q.z)*2.0f; // 1,1   ((float*)&m)[9] = (q.y*q.z - q.w*q.x)*2.0f;        // 1,2   ((float*)&m)[2] = (q.x*q.z - q.w*q.y)*2.0f;        // 2,0   ((float*)&m)[6] = (q.y*q.z + q.w*q.x)*2.0f;        // 2,1   ((float*)&m)[10] = 1.0f - (q.x*q.x + q.y*q.y)*2.0f;// 2,2   return m;}

Cheers.
/def

EDIT:
Quote:
 w = cos(rad/2);x = sb_x * sin(rad/2);y = sb_y * sin(rad/2);z = sb_z * sin(rad/2);l=sqrt(w * w + x * x + y * y + z * z);w/=l; x/=l; y/=l; z/=l;

This would be already unit lenght, if I'm calculating right(if sb_xyz is unit-lenght), so there's no point in re-normalizing.

##### Share on other sites
I think deffer is right. Notice that in his quaternion-to-matrix code, the pluses and minuses in the non-diagonal terms are reversed from yours. Try switching those and see if that doesn't fix the problem, as your current matrix will (I think) produce left-handed rotations in a right-handed coordinate system (the opposite of OpenGL).

Also, I assume you're normalizing in the quat function to allow for non-unit-length rotation axes. I'm not positive about this, but I think if you're going to do this, you need to normalize the axis before constructing the quaternion, rather than normalizing the quaternion after it's already constructed.

##### Share on other sites
Hmm...I suppose the problem is with the Quaternion to Matrix.

However, I got that conversion method from GameTutorial.com's MD3 animation tutorial(http://www.gametutorials.com/gtstore/pc-79-1-md3-animation.aspx), and using that conversion(which is suppose to produce left-handed matrix although OpenGL is righthanded) the MD3 object(it uses Lara Croft) moves correctly !

And, no, I don't use arc cosine, I followed Q30, Q54, and Q56 from Matrix and Quaternion FAQ and there's no Arc Cosine.
Thanks :)

##### Share on other sites
Hold out the thumb, forefinger, and middle finger of your right hand such that your thumb points right, your forefinger points right, and your middle finger points straight back at you. Think of your thumb as X, your forefinger as Y, and your middle finger as Z. This is a right-handed coordinate system.

Now, put your left hand out too, with your thumb and forefinger pointing in the same directions as those on your right hand (not mirrored). Your middle finger will end up pointing away from you. This is a left-handed coordinate system.

##### Share on other sites
I always had problems remembering the difference between a right and left handed coordinate system, until I read "Real time 3D terrain engines using C++ and DirectX 9"

The way it was explained in that book was as follows. In a right handed coordinate system, anything heading along the positive z axis is headed right for you, anything heading along the positive z axis in a left handed system has gone past, or left you.

##### Share on other sites
Quote:
 Original post by OxyacetyleneThe way it was explained in that book was as follows. In a right handed coordinate system, anything heading along the positive z axis is headed right for you, anything heading along the positive z axis in a left handed system has gone past, or left you.

The problem is, that's not necessarily the case. Right/left-handedness refers to the relative ordering of the axes, not the absolute directions. A coordinate system with positive X to the left, positive Y up, and positive Z away from you, would still be a right-handed coordinate system.

##### Share on other sites
Well, thanks for the reply guys. I know what's left/right handed coordinate system.
The problem is, why does that left-handed Q-to-M conversion work well in OpenGL in that MD3 tutorial ?

Notes that some part of the animation algorithm from that tutorial :
-Get rotation matrix for current frame
-Get rotation matrix for next frame
-Change both matrices to Quaternion(Actually, the Matrix-to-Quaternion algorithm they use is also left-handed too)
-Interpolate the quaternion
-Change the interpolated quaternion to matrix and multiply to Modelview matrix.

Oh wait, the left handed Q-to-M conversion works because M-to-Q conversion also left-handed ?

##### Share on other sites
BTW, I have more question, this is about Quaternion and Axis Angle.Anyway, everybody said that interpolation with Quaternion is smoother than Axis Angle and Euler Representation, but they didn't say why ? Can anybody explain this to me ?
Thanks.