PDA

View Full Version : Absolute Rotations: X, Y, and Z



DennisMV
11-30-2002, 07:52 PM
I have an object, and I do these rotations in sequence inside the code: X, Y, and Z. Also, these are absolute rotations. I several sliders which give absolute values for the variables.

There is an inherent problem here. When I want to rotate around only one axis, it's fine.
However, suppose I rotate around Y first,
and then rotate around X. The object rotates now around it's OWN X axis, when I want it to rotate around the GLOBAL X Axis.

Is there a way to do something here ?
I've thought and thought about this, I looked up rotations around parallel axis, even around arbitrary axis, but they do not help ... the rotations are still the same, with the same inherent problem. Is there maybe another way to do this and still get rotations around all the axis ?

Can someone shed some light on this ?

thank you !
Dennis

DennisMV
11-30-2002, 08:24 PM
humm,
I think I got it, but I don't know why..
I found a huge matrix which does all 3 rotations at once, and then it works. If somebody can explain why that works, I'll be very grateful. I'd love a mathematical explanation.

thanks,
Dennis

nexusone
12-01-2002, 04:17 AM
Remember OpenGL first works backwards in how glRotate/translate effect an object.
Every thing is draw in respect the the world origin.

example 1:
glTranslate
glRotate
draw_object
// Object is rotated on its axis 0,0,0 Which could be located at any part of the object. I like to draw objects with there center being 0,0,0.

example 2:

glRotate
glTranslate
Draw_object
// Object is translated out, then rotated around the world axis 0,0,0.

So if you were to translate it 5 units on the x and then rotate it on the x, the object will be moved in a arc fashion based on radius of the translate x value.

I hope that makes sense


Also do you know how to use glPush/PopMatrix()?

// Global stuff, could be use for camera movement
glTranslatef( glob_x, glob_y, glob_x); // Translate world
glRotatef(ax, 1, 0, 0); //Rotate world x axis
glRotatef(ay, 0, 1, 0); //Rotate world y axis
glRotatef(az, 0, 0, 1); //Rotate world z axis

// Object movemt
glPushMatrix()
glTranslatef( objecy_x, object_y, object_x); // Translate Object
glRotatef(ox, 1, 0, 0); //Rotate object x
glRotatef(oy, 0, 1, 0); //Rotate object y
glRotatef(oz, 0, 0, 1); //Rotate object z
Draw_object();
glPopMatrix();

repeat above for each object push/pop for each object.



Originally posted by DennisMV:
I have an object, and I do these rotations in sequence inside the code: X, Y, and Z. Also, these are absolute rotations. I several sliders which give absolute values for the variables.

There is an inherent problem here. When I want to rotate around only one axis, it's fine.
However, suppose I rotate around Y first,
and then rotate around X. The object rotates now around it's OWN X axis, when I want it to rotate around the GLOBAL X Axis.

Is there a way to do something here ?
I've thought and thought about this, I looked up rotations around parallel axis, even around arbitrary axis, but they do not help ... the rotations are still the same, with the same inherent problem. Is there maybe another way to do this and still get rotations around all the axis ?

Can someone shed some light on this ?

thank you !
Dennis

EPHERE
12-01-2002, 05:28 AM
I have already answered this same question before, but the post got lost. I will elaborate again. I am supposing you are using Euler rotations.

The reason your objects are rotating around their own axis is because you are using rotations as a structure of manifold. You have three angles (a,b,c) and a matrix (abbreviated):
[cos(b)cos(a) -cos(b)cos(c) sin(b) ]
[sin(a)sin(b)+... -sin(a)sin(b)... -sin(a)...]
[-cos(a)sin(b)... cos(a)sin(b)... cos(a)cos(b) ]

This orthogonal matrix can be further decomposed into three matrices. These matrices are the rotation matrices around different axes:
Rx(a)=
[1 0 0 ]
[0 cos(a) -sin(a)]
[0 sin(a) cos(a) ]

Ry(b)=
[cos(b) 0 sin(b)]
[0 1 0 ]
[-sin(b) 0 cos(b)]

Rz(c)=
[cos(c) -sin(c) 0]
[sin(c) cos(c) 0]
[0 0 1]

These three matrices multiplied together will give you the rotation matrix along three axes BUT the latter rotations will be dependent on the previous matrix that you multiply them by. Therefore if you have
Rx*Ry*Rz=R
Rx will be independent, Ry will be dependent on Rx (Rx will be its new axis) and Rz will be dependent on Ry and Rx. This kinds of rotations are called pitch-roll, because in airplane design they control the pitch and the roll of the vehicle.

One way to solve this problem would be to just multiply your vertices by ONLY one axis rotation matrix at a time. This is proven to be useful only in certain rare cases.

Another way is to use quaternions. Lets say you want to rotate around a vector u (having | |u| |=1, or in other words u has to be a unit vector) by an angle a.
Then you have a quaternion
q=(s,v)
where
s=cos(a/2)
v=sin(a/2)*u

You can then further decompose this quaternion into four components:
q=[s,l,m,n]
where l,m and n are the three imaginary values.

From this you get the rotation matrix:

[s^2+l^2-m^2-n^2 2(lm-sn) 2(ln+sm)]
[2(lm+sn) s^2-l^2+m^2-n^2 2(mn-sl)]
[2(ln-sm) 2(mn+sl) s^2-l^2-m^2=n^2]

You can go ahead and multiply three or four quaternions together to get a structure of manifold.

I hope this helps.

EPHERE

DennisMV
12-03-2002, 09:13 AM
Wow, I think I sort of got it now.

the quaternions seem somewhat complex.
One way I saw was (I guess like you said) to just multiply by one matrix at a time, and modify your object in the process. However, OpenGL doesn't explicitly modify the object, so that won't work as well.

thanks,
Dennis