Get Z vector of rotation matrix?

Member
Posts: 281
Joined: 2009.04
Post: #1
I had created a quaternion of rotations which I then create a matrix from using the following code:

Code:
matrix quatToMatrix(quaternion quat) {
    matrix qmatrix;    
    
    qmatrix.m[0]  = (1.0f - (2.0f * ((quat.y * quat.y) + (quat.z * quat.z))));
    qmatrix.m[1]  =         (2.0f * ((quat.x * quat.y) + (quat.z * quat.w)));
    qmatrix.m[2]  =         (2.0f * ((quat.x * quat.z) - (quat.y * quat.w)));
    qmatrix.m[3]  = 0.0f;
    qmatrix.m[4]  =         (2.0f * ((quat.x * quat.y) - (quat.z * quat.w)));
    qmatrix.m[5]  = (1.0f - (2.0f * ((quat.x * quat.x) + (quat.z * quat.z))));
    qmatrix.m[6]  =         (2.0f * ((quat.y * quat.z) + (quat.x * quat.w)));
    qmatrix.m[7]  = 0.0f;
    qmatrix.m[8]  =         (2.0f * ((quat.x * quat.z) + (quat.y * quat.w)));
    qmatrix.m[9]  =         (2.0f * ((quat.y * quat.z) - (quat.x * quat.w)));
    qmatrix.m[10] = (1.0f - (2.0f * ((quat.x * quat.x) + (quat.y * quat.y))));
    qmatrix.m[11] = 0.0f;
    qmatrix.m[12] = 0.0f;
    qmatrix.m[13] = 0.0f;
    qmatrix.m[14] = 0.0f;
    qmatrix.m[15] = 1.0f;
    
    return qmatrix;
}

(ThemsAllTook may recognise this code Smile, thanks for your useful resources)

But when I try to get the z vector (like the quaternion is an aeroplane and the z vector is forward) straaaange things happen.

Here's the code:

Code:
    shipRotation.z = pitch   * DEG_TO_RAD ; // converts the pitch to radians
    shipRotation.y = heading  * DEG_TO_RAD ; // likewise
    shipRotation.x = roll * DEG_TO_RAD; // and roll
    
    q1 =  eulerToQuat(shipRotation); // makes q1

    q2 = quatMult(q1,q2); // multiplies with the existing quaternion
    
    shipMatrix = quatToMatrix(q2); // creates matrix

    
    glMultMatrixf(  shipMatrix.m ); // multiplies matrix (was made identity at start of frame)

    translation.x =  shipMatrix.m[8]; // look at the matrix struct for this
    translation.y = shipMatrix.m[9]; // ''
    translation.z =  shipMatrix.m[10];// ''
    
    translation = vectorByScalar(translation, airspeed); // multiplies vector by scalar
            
    xp = translation.x;
    yp = translation.y;
    zp = translation.z;    
    
    glTranslatef(-xp ,-yp,zp);


Why is this not working? Most of the functions are from ThemsAllTooks handy tutorials but I can post them if you like.

NeHe's way involves only two axes (axis?).

Thanks in advance

mikey

P.S. I did post on OpenGL forums but with some not very helpful replies so you'll probably find them.

~ Bring a Pen ~
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
Pulling a front vector straight out of the matrix probably isn't what you want to do. I'd set up a vector to point at whatever is your forward direction in the identity orientation, then multiply it by your matrix to get the desired result. Something like this:

Code:
Vector3 vector = {0.0f, 0.0f, 1.0f};
vector = Matrix_multiplyVector3(matrix, vector);
// vector now contains a forward vector for your current orientation (may need to be normalized if your matrix shears or scales)

Glad you found my code useful!
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #3
Though that is equivalent to extracting the 3rd column. Wink Are your matrices stored row or column major? You might be extracting the row instead of the column.

Still, for readability's sake I'd take ThemsAllTook's suggestion. It might be 0.1% slower, but it's less lines of code to write, understand, and potentially screw up.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #4
Hmm. I change my code to:

Code:
    glMultMatrixf(  shipMatrix.m );
    
//    glGetFloatv(GL_MODELVIEW_MATRIX, shipMatrix.m);
    
    shipFinalRotation = matrixByVector(shipMatrix , shipFinalRotation);
    
    
    translation = vectorByScalar(shipFinalRotation, airspeed);
    
    xp += translation.x;
    yp += translation.y;
    zp += translation.z;    
    
    
    glTranslatef(-xp ,-yp,-zp);
    /*

But the screen jitters around in a circle along the z plane?

~ Bring a Pen ~
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #5
Skorche Wrote:Though that is equivalent to extracting the 3rd column. Wink

Now that I think about it again, you're right. When I wrote that post, I'd somehow reached a different conclusion. Must've been tired. ZZZ

Only applicable if {0, 0, 1} is your identity forward vector, though.
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #6
So why does nothing happen when I change my code to:

Code:
        translation.x = shipMatrix.m[20];
    translation.y = shipMatrix.m[21];
    translation.z = shipMatrix.m[22];
    
    
    translation = vectorByScalar(translation, airspeed);
    
    xp += translation.x;
    yp += translation.y;
    zp += translation.z;    
    
    
    glTranslatef(xp ,yp,zp);
?

~ Bring a Pen ~
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #7
20, 21, 22? How large is this matrix? Those are well outside the bounds of 4x4.
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #8
Oh sorry I meant to type 12,13 and 14. But the result is still the same Sad.

~ Bring a Pen ~
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #9
mikey Wrote:There are 0100 kinds of people in the world: those who understand binary, those who don't , and those who can't count.

4 kinds of people? 64? Sorry for being OT, but this is just puzzling LOL
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #10
You answered this question yourself by counting the binary and counting decimals. Therefore you can count and create the fourth catergory. Smile

~ Bring a Pen ~
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #11
Anyway, I meant to type 8,9 and 10. On further inspection these produce an odd orbiting motion. Sorry to seem stupid but I really can't see why this isn't working.

~ Bring a Pen ~
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #12
Anyone? .........

~ Bring a Pen ~
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #13
It's difficult for us to troubleshoot without more information. Maybe if you post a video or some screenshots?
Quote this message in a reply
Member
Posts: 281
Joined: 2009.04
Post: #14
OK, here's a video:
http://tinypic.com/player.php?v=2e6c5ew&s=6

You probably want to keep track of the readouts at the top left.

~ Bring a Pen ~
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #15
So, the way the ship jitters is the problem? It's pretty hard to tell what's going on in a whole-system test like this. If I were trying to debug this, I'd pull out the relevant code into an as-small-as-possible test app so that I could inspect and experiment with the problematic behavior in isolation. Once you solve the problem there, you should be able to bring it back into your main application and have everything work better.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Strange problem while using 4x4 Rotation Matrix Man With No Name 6 3,983 Mar 11, 2008 08:00 AM
Last Post: Man With No Name
  Rotation along directional vector evenmybird 3 2,654 Aug 25, 2006 10:01 PM
Last Post: Hasty
  Using a matrix to generate a new vector position imikedaman 6 4,358 Jul 16, 2006 01:17 PM
Last Post: imikedaman
  Simple 2D Matrix Rotation isn't working Joseph Duchesne 2 2,884 Jun 19, 2005 08:41 AM
Last Post: Joseph Duchesne