# converting between quaternions and matrices

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

## Recommended Posts

I have two functions, one to create a 4x4 matrix from a quaternion, and one to create a quaternion from a 4x4 matrix. To test them I create an identity matrix and an identity quaternion identity matrix: 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 0.000000 1.000000 identity quaternion: 0.000000 0.000000 0.000000 1.000000 quat_from_matrix output: 0.000000 0.000000 0.000000 1.000000 matrix_from_quat output: 0.250000 0.375000 -0.500000 0.000000 0.250000 0.500000 0.500000 0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.000000 1.000000 quat_from_matrix output: 0.250000 0.375000 -0.500000 0.000000 something seems to be wrong as i can't convert twice and get the same thing back. here are my two functions:
void quat_from_matrix4(quat q, matrix4 m)
{   float trace=m[0]+m[5]+m[10]+1;
if (trace>EPSILON)
{   float s=0.5f/sqrtf(trace);
q[0]=(m[9]-m[6])*s;
q[1]=(m[2]-m[8])*s;
q[2]=(m[4]-m[1])*s;
q[3]=0.25f/s;
}
else
{   if (m[0] > m[5] && m[0] > m[10])
{   float s=2.0f*sqrtf(1.0f+m[0]-m[5]-m[10]);
q[0]=0.25f/s;
q[1]=(m[1]+m[4])*s;
q[2]=(m[2]+m[8])*s;
q[3]=(m[6]-m[9])*s;
}
else if (m[5] > m[10])
{   float s=2.0f*sqrtf(1.0f+m[5]-m[0]-m[10]);
q[0]=(m[1]+m[4])*s;
q[1]=0.25f*s;
q[2]=(m[6]+m[9])*s;
q[3]=(m[2]-m[8])*s;
}
else
{   float s=2.0f*sqrtf(1.0f+m[0]-m[5]-m[10]);
q[0]=(m[2]+m[8])*s;
q[1]=(m[6]+m[9])*s;
q[2]=0.25f*s;
q[3]=(m[1]-m[4])*s;
}
}
}

void matrix4_from_quat(matrix4 mat, quat q)
{   float xx=q[0]*q[0];
float xy=q[0]*q[1];
float xz=q[0]*q[2];
float xw=q[0]*q[3];

float yy=q[1]*q[1];
float yz=q[1]*q[2];
float yw=q[1]*q[3];

float zz=q[2]*q[2];
float zw=q[2]*q[3];

//first column
mat[0]=1.0f-2.0f*(yy+zz);
mat[1]=2.0f*(xy-zw);
mat[2]=2.0f*(xz+yw);
mat[3]=0.0f;
//second column
mat[4]=2.0f*(xy+zw);
mat[5]=1.0f-2.0f*(xx+zz);
mat[6]=2.0f*(yz-xw);
mat[7]=0.0f;
//third column
mat[8]=2.0f*(xz-yw);
mat[9]=2.0f*(yz+xw);
mat[10]=1.0f-2.0f*(xx+yy);
mat[11]=0.0f;
//fourth column
mat[12]=0.0f;
mat[13]=0.0f;
mat[14]=0.0f;
mat[15]=1.0f;
}


can anyone spot any mistakes?

##### Share on other sites
Should this:

else {
float s=2.0f*sqrtf(1.0f+m[0]-m[5]-m[10]);

Be:

else {
float s=2.0f*sqrtf(1.0f+m[10]-m[0]-m[5]);

?

##### Share on other sites
You're right, nice catch.

I made the correction and the output is unchanged, though. If you look at the output the quat_from_matrix4 function appears to produce correct output (i.e. identity quat from an identity transformation matrix).

it's the matrix4_from_quat that doesn't produce identity from identity. i'm wondering if this is a special case the function doesn't handle...

oh yeah, in case this wasn't obvious the matrices are stored in column-major ordering and the the quaternions are in the order x,y,z,w.

##### Share on other sites
I couldn't find an error in your quat-to-matrix code. Something is a little suspicious, though, because in the output that you posted, element 14 is 1, but the code should have set it to zero. If you haven't already found the problem, you might try stepping through the code line be line.

##### Share on other sites
hmm... I do the matrix to quaternion conversion differently. Look at this article.

Hope this helps.

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633726
• Total Posts
3013569
×