# How can I rotate around 3 axes in opengl?

October 14, 2008 2:17 PM Subscribe

Please help me wrap my head around this 3d graphics math. :(

I'm writing an application in OpenGL for learning purposes and I'm trying to allow the user to modify the angle by which I rotate an object around the X axis, the Y axis, and the Z axis.

My problem is that I only know how to do the following:

glRotatef(xAngle,1,0,0);

glRotatef(yAngle,0,1,0);

glRotatef(zAngle,0,0,1);

(basically, rotate around the x axis, then around the y axis, then around the z axis)

This doesn't work because, essentially, after rotating, say, 90 degrees about the x-axis, the y and z axes are no longer where they used to be. See this crude picture for more information on what I'm talking about.

What I'm looking for is best practice on what to do in this situation. I have two opengl books and I've searched the internet and I haven't been able to find out anything about this. Surely this must be a common problem?

Code or (well-explained, not dry) math theory would be much appreciated. Thanks!

I'm writing an application in OpenGL for learning purposes and I'm trying to allow the user to modify the angle by which I rotate an object around the X axis, the Y axis, and the Z axis.

My problem is that I only know how to do the following:

glRotatef(xAngle,1,0,0);

glRotatef(yAngle,0,1,0);

glRotatef(zAngle,0,0,1);

(basically, rotate around the x axis, then around the y axis, then around the z axis)

This doesn't work because, essentially, after rotating, say, 90 degrees about the x-axis, the y and z axes are no longer where they used to be. See this crude picture for more information on what I'm talking about.

What I'm looking for is best practice on what to do in this situation. I have two opengl books and I've searched the internet and I haven't been able to find out anything about this. Surely this must be a common problem?

Code or (well-explained, not dry) math theory would be much appreciated. Thanks!

I haven't done any 3D programming in years, but if I recall correctly, OpenGL is conceptually stack-based in terms coordinate translations. Before you rotate your object, you need to translate your coordinate system so that the center of your rotation is the center of your coordinate space. I think this is done through something like:

glPushMatrix();

glTranslate(whatever translation puts your rotation point at the origin of your coordinate space);

(render objects in this translated coordinate space, etc);

glPopMatrix(); //restores your coordinate space to the way it was before you pushed it.

On preview, @sbutler's method is probably more efficient, but the method I describe is less mind-bending if you're in the process of learning OpenGL.

posted by strangecargo at 2:34 PM on October 14, 2008

glPushMatrix();

glTranslate(whatever translation puts your rotation point at the origin of your coordinate space);

(render objects in this translated coordinate space, etc);

glPopMatrix(); //restores your coordinate space to the way it was before you pushed it.

On preview, @sbutler's method is probably more efficient, but the method I describe is less mind-bending if you're in the process of learning OpenGL.

posted by strangecargo at 2:34 PM on October 14, 2008

sbutler, I looked into quaternions earlier actually, and found (though I could be wrong) that they did not solve my problem. I think the biggest problem was that I couldn't find *anything* about how to turn my three rotations (about the X,Y, and Z axes) into one vector and one angle. Multiplying the quaternions corresponding to my X,Y and Z rotations didn't seem to do the trick either.

strangecargo, I actually am rotating at the origin ^^

Thanks

posted by mebibyte at 6:50 PM on October 14, 2008

strangecargo, I actually am rotating at the origin ^^

Thanks

posted by mebibyte at 6:50 PM on October 14, 2008

Is this a theoretical question, or a "my code gives the wrong output" question? Because I think I know how it should work, but that doesn't help if you've already tried the solution you posted and are getting wrong results.

posted by sbutler at 7:33 PM on October 14, 2008

posted by sbutler at 7:33 PM on October 14, 2008

You can find out more about the "angles and axes" way of describing rotations by googling "Euler angles". You should also be able to find discussions of various problems with Euler angles and ways to convert back and forth to quaternions. In general you're just better off using quaternions for manipulating rotations. I like the various articles by Ken Shoemake on the subject. Some of his stuff is pretty mathematically hardcore, but if I remember correctly (it's been a while) he has also done a good job writing more approachable material. If you want to create a mouse-driven GUI rotation system, definitely use his "arcball" system.

posted by madmethods at 7:38 PM on October 14, 2008

posted by madmethods at 7:38 PM on October 14, 2008

What you've discovered is that rotations aren't commutative. More generally, since these rotations are linear (and affine) transformations of your coordinate system which can be represented by matrix multiplication, matrix multiplication is not commutative.

Your representation of yaw/pitch/roll is similar to Euler angles. Euler angles are a pain to deal with mathematically. Working with the transform matrix directly is easy but can be trouble since it's too flexible— you want to represent an orientation, not orientation, scale, skew, etc., and roundoff can creep in 'way too easily. Quaternions are an ideal middle ground.

posted by hattifattener at 7:42 PM on October 14, 2008

Your representation of yaw/pitch/roll is similar to Euler angles. Euler angles are a pain to deal with mathematically. Working with the transform matrix directly is easy but can be trouble since it's too flexible— you want to represent an orientation, not orientation, scale, skew, etc., and roundoff can creep in 'way too easily. Quaternions are an ideal middle ground.

posted by hattifattener at 7:42 PM on October 14, 2008

Note: I need to preview.

posted by hattifattener at 7:43 PM on October 14, 2008

posted by hattifattener at 7:43 PM on October 14, 2008

Convert Euler angles to quaternions. And, glRotatef just happens to take a rotation + vector. How handy :)

posted by sbutler at 7:52 PM on October 14, 2008

posted by sbutler at 7:52 PM on October 14, 2008

Conceptual leap filter: Any arbitrary series of rotations can be treated as a single rotation about a specific axis. A quaternion consists of four numbers of which three represent the direction of the rotation axis and the fourth is the angular distance of the rotation.

posted by LastOfHisKind at 9:44 PM on October 14, 2008

posted by LastOfHisKind at 9:44 PM on October 14, 2008

This thread is closed to new comments.

posted by sbutler at 2:29 PM on October 14, 2008