PDA

View Full Version : Rotation Matrix



yeahdixon
07-28-2010, 09:39 AM
I am having trouble with rotations ,

I am drawing a cube and want to rotate on two axis x and y.

glRotatef(fXrot,1,0,0);
glRotatef(fYrot,0,1,0); //cause gimbal lock like effects

If i rotate first on the x axis using glrotate , then what is the correct vector axis of rotation/angle such that the rotation on the yaxis always rotates the cube on the global yaxis? If i use the glRotatef(fYrot,0,1,0) in the manner posed above it rotates after the x axis rotation, spinning the cube in the local axis.

consider the example on a front facing cube with the following rotations:

glRotatef(90,1,0,0);
glRotatef(45,0,1,0);

this actually produces a diamond because the cube is first rot 90degress facing down, and then twisted in the local x axis 45 degrees twisting it into a diamond (see attached)

after doing:
glRotatef(90,1,0,0); now facing down
how would i get this equation (or the equivalent):
glRotatef(fRotX,v0,v1,v2);
so that after the sec desired result the cube will end up facedown but the left front corner facing the into the camera (see attached)

Rosario Leonardi
07-28-2010, 02:22 PM
"produces a diamond"
Alchemical programming.. wonderful :D

Ehm... sorry... let's return serious, this it's a serious forum.
You want to rotate your cube on the GLOBAL x axis, and then apply a rotation on the GLOBAL y axis.
As you notice the rotation are local, so to make a local rotation to seem global you must cheat and compute the global Y axis after the X rotation.

rotate(another_angle, Xaxis);
rotate(some_angle, someAxis);
drawDiamond();
note: glRotate are applied in the opposite order

glRotate(another_angle, 1.f, 0.f, 0.f) is like multiplying the current matrix by this matrix



1 0 0 0
0 cos(angle) -sin(angle) 0
0 sin(angle) cos(angle) 0
0 0 0 1
Wow, what we have here, an orthonormal matrix, gl programmers love orthonormal matrix cause they have a lot of wonderful properties.
The local Y axis is the second column, but we want the inverse (so we take the second raw).
Here it is:


float radAngle = (xAngle/180.f)*3.1415f;
glRotatef(xAngle, 1.f, 0.f, 0.f);
glRotatef(yAngle, 0.f, cos(radAngle), -sin(radAngle));
drawDiamonds();

yeahdixon
07-28-2010, 03:04 PM
OK TY, your right that seems to do the trick and makes sense.

But, now i noticed that the same problem is happening on the opposite axis. Rotation over the x-axis is always perfect but the rotation over the y is now dependent on the x axis.

Rosario Leonardi
07-28-2010, 04:15 PM
Combing rotation are really order dependent. If you want to rotate on the Y and then on the X you must do the inverse trick.
Rotating all three global axis is very painful and probably is better to avoid using glRotatef and use a matrix library to make the computation and then apply the matrix with glLoadMatrix

yeahdixon
07-28-2010, 09:17 PM
I got this to work correctly using quaternions: It seems the right way to do what i was trying to accomplish.

first create the quaternion representation of the angles
then each frame multiple the quaternion to an accumulating quaternion , then finally convert that quaternion to matrix form to multiply the current matrix. Here is the main code of the loop:

Quaternion3D Rotation1=Quaternion3DMakeWithAxisAndAngle(Vector3 DMake(-1.0f,0,0), DEGREES_TO_RADIANS(globalRotateX));
Quaternion3DNormalize(&Rotation1);

Quaternion3D Rotation2=Quaternion3DMakeWithAxisAndAngle(Vector3 DMake(0.0f,-1.0f,0), DEGREES_TO_RADIANS(globalRotateY));
Quaternion3DNormalize(&Rotation2);


Matrix3D Mat;
Matrix3DSetIdentity(Mat);
Quaternion3DMultiply(&QAccum, &Rotation1);

Quaternion3DMultiply(&QAccum, &Rotation2);

Matrix3DSetUsingQuaternion3D(Mat, QAccum);
globalRotateX=0;
globalRotateY=0;

glMultMatrixf(Mat);

then draw cube

MaxH
07-29-2010, 10:32 AM
I got this to work correctly using quaternions: It seems the right way to do what i was trying to accomplish.

glMultMatrixf(Mat);
Congrats on finding a solution to your problem. But you made it sound more complicated than it really is. Quaternions aren't the key, MultMatrix is the key. Screen or object space rotations can be accomplished with careful manipulation of rotation matrices and the MultMatrix command.

yeahdixon
07-29-2010, 03:53 PM
yeah, true, I figured that the same can be done with matrices , since you can always swap between quaternion and rotation matrices. So where there is a quaternion I guess there could be the equivalent matrix. But the above wasn't too much code, plus now i can use SLERP to animate between them. thanks again.

keerthi
08-12-2010, 12:32 AM
hi even im facing such problem .. but im not so clear with the solutuion .. so can u be more clear with this issue or if any example or code please share it , thhnk you

jmanji
09-19-2010, 06:41 AM
I also have the same problem. Rosario Leonardi's solution does not seem to solve it...

MaxH
09-19-2010, 09:26 PM
I have a demo that may address your problem.

The source code is at - www.mfwweb.com/OpenGL/Special_Rotations/Source.c (http://www.mfwweb.com/OpenGL/Special_Rotations/Source.c)

You'll have to compile and link it with OpenGL and GLUT.

Look at the routine 'Keyboard' to see which keys do which rotations.