What math is needed to combine two or more rotations?

Started by
8 comments, last by erissian 15 years, 11 months ago
Ok, new to OpenGL and all the math that goes along with it and have a quick question. OpenGL has a function called glRotatef(a,x,y,z) which if I understand correctly rotates the projection around the vector x,y,z by angle a. My question is, if I have 2 or more glRotatef() functions, what math would be needed to combine those into a single equivalent function? So for example say I have this code:

a1=5f;
x1=1.0f;
y1=0.5f;
z1=0.25f;

a2=3f;
x2=.75f;
y2=.5f;
z2=.75f;

glRotatef(a1,x1,y1,z1);
glRotatef(a2,x2,y2,z2);
I want to combine into this:

a1=5f;
x1=1.0f;
y1=0.5f;
z1=0.25f;

a2=3f;
x2=.75f;
y2=.5f;
z2=.75f;

// Do some math to calculate a3,x3,y3,z3

glRotatef(a3,x3,y3,z3);  // accomplishes some rotation in a single command
What I am looking for is the math needed to calculate a3,x3,y3,z3 in the above example. Thanks!!
Advertisement
You should look for quaternions. You can express the two rotations as quaternions, multiply and then extract the angle and axis from the result. This is likely to be the easiest way.

However, may I ask, why do you want to do this?
It’s probably better to create (and pass to OpenGL) a matrix than calculating the vector and the angle. To combine the two operations you can multiply the two quaternions or matrices that represents the rotations.
Quote:Original post by pjyelton
// Do some math to calculate a3,x3,y3,z3

glRotatef(a3,x3,y3,z3); // accomplishes some rotation in a single command

What I am looking for is the math needed to calculate a3,x3,y3,z3 in the above example.

Thanks!!


3D rotation can't properly be expressed by a single rotation. Picture an airplane being rotated from facing the vector <1,0,0> to the vector <0.707, 0.0, 0.707>. While easy enough to express merely that as a single rotation, let's say that we also want to make sure that the airplane's "up" vector is <0,1,0> in both cases. It's not really possible.

That's why we use matrices and quaternions. If you have a series of small, incremental rotations, quaternions may be best. In more general cases, matrices should do fine.

[Edited by - erissian on May 11, 2008 1:06:25 AM]
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Quote:Original post by erissian
3D rotation can't properly be expressed by a single rotation.

Say what? That statement refutes itself. In any case, the orientation of a body can be expressed with an angle and an axis. The 'difference' between any two orientation can also be expressed in such a way, although there maybe multiple ways of presenting the same orientation or rotation.

Quote:Original post by erissian
That's why we use matrices and quaternions.

Rotation matrices and quaternions express exactly the same thing. Just in two different ways, with different pros and cons.
Thanks for the help guys, I'll take a look at quaternions and see if its what I'm looking for. As to what I'm trying to do, bear with me since I'm very new to coding and 3d math so its very likely whatever solution you guys would have come up with to solve the same problem is light years ahead of where I'm at.

I've completed many different programs that have involved a single rotating cube in various forms and I figured my next challenge would be to put it all together and create a 3D Rubiks cube. The cube consists of 27 "blocks" that form a larger cube centered on the origin. What I couldn't figure out was how to keep track of the orientation of each individual block since they can all be rotated independantly from the main cube.

My solution was to have each block object contain an X,Y,Z and angle, then each frame I would load the identity matrix to reset the projection, then cycle through and rotate each block by each their individual X,Y,Z,angle values using glRotatef() and redrawing. If the user rotates the entire cube, I would use the math I asked for to update these values for every block. If the user twists a side, then I would update only the values of the blocks contained on the moving side.

Make sense? If it does like I said I'm sure theres a much simpler solution to my problem that a more experienced coder would see instantly.

[Edited by - pjyelton on May 10, 2008 11:33:37 PM]
Quote:Original post by SnotBob
Quote:Original post by erissian
3D rotation can't properly be expressed by a single rotation.

Say what? That statement refutes itself. In any case, the orientation of a body can be expressed with an angle and an axis. The 'difference' between any two orientation can also be expressed in such a way, although there maybe multiple ways of presenting the same orientation or rotation.


Sorry, that was poorly worded. Now that I'm less distracted, let me clarify: A single rotation about an arbitrary axis is insufficient to cover all the degrees of freedom available in three dimensions of space. You need at least two rotations in sequence to cover all of those possibilities, at least in rectilinear coordinates, otherwise you need more. Back to the airplane, you can make the nose point in any direction using a single rotation, but you have no control over where the wings will be pointing.

I bring this up because pjyelton appears to be looking for a way to calculate the arguments to a single glRotate() call that replaces an arbitrary number of rotations, along a series of arbitrary axes.

Quote:
Quote:Original post by erissian
That's why we use matrices and quaternions.

Rotation matrices and quaternions express exactly the same thing. Just in two different ways, with different pros and cons.


Quaternions and 4x4 rotation matrices can be made to express the same information, and for 3D graphics they are used to identical ends, but they are in fact very different beasts and operate on themselves in unique ways.

The biggest benefit of quaternions over matrices is that they are far more convenient to interpolate, followed by their size in memory, being less expensive computationally, and, if need be, ease of normalization.

Matrices are more intuitive for beginners to use, are easy to construct, are the actual format used in transformations, and allow the incorporation of other transformations.

There is plenty of information on both matters on this board, under Articles & Resources. They both have places where they excel, and I personally use both liberally through my programs, depending on the particular problem.

[Edited by - erissian on May 11, 2008 2:34:34 AM]
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Quote:Original post by erissian
Sorry, that was poorly worded. Now that I'm less distracted, let me clarify: A single rotation about an arbitrary axis is insufficient to cover all the degrees of freedom available in three dimensions of space. You need at least two rotations in sequence to cover all of those possibilities, at least in rectilinear coordinates, otherwise you need more. Back to the airplane, you can make the nose point in any direction using a single rotation, but you have no control over where the wings will be pointing.

I bring this up because pjyelton appears to be looking for a way to calculate the arguments to a single glRotate() call that replaces an arbitrary number of rotations, along a series of arbitrary axes.

The axis-angle representation can represent every rotation in 3D. A rotation is an isometry in the space that leave the origin fixed and preserve the orientation. The group of matrices that represent them is the special orthogonal group SO(n).

I want to demonstrate that every rotation in 3D is a rotation around an axis.
Consider the following family of matrices
Rθ = [cosθ -sinθ 0; sinθ cosθ 0; 0 0 1]
that represent the rotations around the z-axis. I’ll demonstrate that all the matrices in SO(3) are equivalent to some Rθ by some change of coordinate (that depends on the axis of rotation).

The first step is to show that 1 is an eigenvalue of A.
det(A - I3) = det(A - AAT) = det(A(I3 - A)T) = det(A)det((I3 - A)T) = -det(A - I3) = 0
A - I3 is singular and there is a vector w such that Aw = w. Using this vector I can create the orthonomal basis {w1, w2, w3} where w3 = w/||w|| and w1 and w2 are two orthonormal vector perpendicular to w. Being an orientation preserving orthonormal transformation, A must restrict to a rotation in the plane generated by w1 and w2 of an angle θ.
Aw1 = w1cosθ + w2sinθ
Aw2 = -w1sinθ + w2cosθ

Let P denote the matrix whose column vectors are w1, w2 and w3. The columns of AP are, by definition of matrix product, Aw1, Aw2 and Aw3 and I can write the following formulas:
AP = PRθ
P-1AP = Rθ

In your example the axis of rotation is the up vector the angle is π/4 (I think).
pjyelton: I gather that you wish to simply keep track of the orientation of each block. If that is the case, you can just use matrices.

erissian: In addition to what apatriarca said, while quaternions and matrices in general are quit different, a 3x3 matrix set up for rotation expresses the same thing as a quaternion used for rotation. They both contain the same information and can easily be converted to each other.
Quote:Original post by SnotBob
erissian: In addition to what apatriarca said, while quaternions and matrices in general are quit different, a 3x3 matrix set up for rotation expresses the same thing as a quaternion used for rotation. They both contain the same information and can easily be converted to each other.


Quote:Quaternions and 4x4 rotation matrices can be made to express the same information, and for 3D graphics they are used to identical ends,


@apatriarca

I have to concede. I'm not sure where my mind was today :)
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)

This topic is closed to new replies.

Advertisement