Advertisement

Rotation around arbitary axis

Started by March 27, 2000 04:12 AM
15 comments, last by Void 24 years, 11 months ago
How does one derive the transformation matrix to calculate a rotation around an arbitary axis (RHS)? The formula I use is Matrix = uu^T + cos(angle)(I - uu^T) + sin(angle)S where u - normalized axis vector u^T - transpose of u I - 3x3 identity matrix S - [ 0 -z y z 0 -x -y x 0] But for axis (-0.25, 0.93, 0.25) rotation 90 deg, the vector (1, 0, 0) will become (0, 0, -1) instead of something like (0, 0.5, 0.83). Can anyone explain plz??
Hmm... I don''t think the formula you are using is correct. It could be, I just can''t figure out what the heck it''s doing.

Here''s another one:

Let U be the unit vector along the rotation axis.
Let (a, b, c) be the coordinates of U.
Let d be equal to sqrt(b ^ 2 + c ^ 2)
Let T be the angle to rotate by.

Then, given the following matrices:
RX = [1     0     0     0]     [0    c/d  -b/d    0]     [0    b/d   c/d    0]     [0     0     0     1]RY = [d  0  -a  0]     [0  1   0  0]     [a  0   d  0]     [0  0   0  1]RZ = [cos(T)  -sin(T)  0  0]     [sin(T)   cos(T)  0  0]     [  0        0     1  0]     [  0        0     0  1] 

The final matrix to rotate by is:
R = (RX^-1)*(RY^-1)*RZ*RY*RX

Conceptually you multiply by RX to align the rotational coordinate space with the x-axis and by RY to align the rotational coordinate space with the y-axis. Then RZ rotates about the z-axis and (RY^-1) restores the y-axis and (RX^-1) restores the x-axis.
Advertisement
I always use this code:

void MatrixSetRotate(MATRIX3D &Mtx, const VECTOR3D &Axis, float r){  // The axis vector must be of unit length  VECTOR3D V = Normalize(Axis);  // Compute the rotation matrix    float c = (float)cos(r);  float s = (float)sin(r);  Mtx._00 = (V.x * V.x) * (1.0f - c) + c;  Mtx._01 = (V.y * V.x) * (1.0f - c) + (V.z * s);  Mtx._02 = (V.z * V.x) * (1.0f - c) - (V.y * s);  Mtx._03 = 0;  Mtx._10 = (V.x * V.y) * (1.0f - c) - (V.z * s);  Mtx._11 = (V.y * V.y) * (1.0f - c) + c;  Mtx._12 = (V.z * V.y) * (1.0f - c) + (V.x * s);  Mtx._13 = 0;  Mtx._20 = (V.x * V.z) * (1.0f - c) + (V.y * s);  Mtx._21 = (V.y * V.z) * (1.0f - c) - (V.x * s);  Mtx._22 = (V.z * V.z) * (1.0f - c) + c;  Mtx._23 = 0;  Mtx._30 = 0;  Mtx._31 = 0;  Mtx._32 = 0;  Mtx._33 = 1;}  


To derive the above matrix you can do the following steps:

1. Rotate about the x-axis so that the rot-axis is aligned with the xz-plane
2. Rotate about the y-axis so that the rot-axis is aligned with the z-axis
3. Rotate the desired angle about the z-axis
4. Do the inverse of 2
5. Do the inverse of 1

Hmm, at closer inspection this is the same as SiCrane's way, just in other words.

You should note that my matrix above is designed to be used like this:

TransformedVector = Vector * Matrix;

From what I can tell about SiCrane's it is designed to be used like this:

TransformedVector = Matrix * Vector;

To convert between the two you only need to make a simple transposition of the matrix elements.



Edited by - Spellbound on 3/27/00 5:34:20 AM
I see.. thanks.

the formula was taken from the OpenGL red book and some other maths resource I found, so I blindly believed them.
Spellbound

On close inspection, your derived matrix is the same

For axis (-0.250563, 0.93511, 0.250563) with angle 1.63783 (rad) (about 93 degrees)

the matrix dervied (mine) is something like

0 -0.5 0.86 0
0 0.86 0.5 0
-1 0 0 0
0 0 0 1

So a vetor (1, 0 ,0) postmultiplied will return (0, 0 ,-1) which looks totally wrong.
Ah. It seems that you''ve got the order of matrix multiplication reversed. Spellbound''s Matrix works like

V'' = (V^T * M)^T

It seems like you''ve been trying

V'' = M * T

For the previous method, for your case it returns (0, -.5, .86) which looks fine.
Advertisement
Sicrane

Is (0, -0.5, 0.86) correct?

Since it is a positive rotation in a right hand system, shouldn''t the z values be negative, rather than positive??

I have not tried your method because I don''t have an inverse matrix function written yet (Looks like must write one now)
You could be right about that. In that case, I guess you''ll have to flip the sign of the angle for his matrix.
Sicrane:

Are u using a right or left hand system? I cannot seem to derive your rotation around Y axis.

Have I got I totally wrong or what?

My friend keeps insisting me that the maths is correct.

Rotation around (-0.250563, 0.935113, 0.250563) , angle is 1.63783 rad (about 93 deg)

will cause the vector (1, 0, 0) to return (0, 0, -1).

Visually I think it should return something like
(0, -0.5, -0.86) but I can''t seems to get the maths to produce results like that.

Can someone plz verify?
My matrix is for Direct3D to use it in OpenGL you should transpose it.

Right-handed and left-handed systems both use the same rotation matrices it is the meaning of the rotation angle that changes.

This topic is closed to new replies.

Advertisement