## converting xyz rotation to something else

Member
Posts: 320
Joined: 2003.06
Post: #1
Hi all
I need to convert a rotation that is stored in the format xyz where x is the angle of rotation about the x axis, y the rotation about the y axis, z about z, and the rotations are preformed in that order.

I need this rotation in either an axis-angle, a euler angle, or matrix, it does not matter which.

Does anyone know how to do this? I'm currently looking over maths pages but without a huge amount of luck.

Cheers,
David

Chopper, iSight Screensavers, DuckDuckDuck: http://majicjungle.com
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
that's already euler angles...

probably the easiest is to treat it as three axis-angle rotations, generate 3x3 matrices for each, and multiply the matrices to get the combined rotation matrix.
Member
Posts: 320
Joined: 2003.06
Post: #3
it seemed from what I read that the euler angles I have to convert to were zxz...
But yeh, that sounds good, I've tried genertaing the matrix all at once, but I think I do need to generate all 3 and multiply them all together. Cheers.
David

Chopper, iSight Screensavers, DuckDuckDuck: http://majicjungle.com
kberg
Unregistered

Post: #4
If you know you need to multiply all three together beforehand (and may be doing this a lot) it may be worth the time to pop open maple or matlab and work out the coefficients. I've done it in the past when I was trying to work an algorithm to break a matrix back into euler angles, and IIRC the resulting matrix wasn't all that bad. I think 5 terms at most for a given element in the resulting 3x3 matrix, but much cheaper then doing 3 full matrix multiplies.

[edit: even without maple it would probably take only a few minutes to work out by hand..]
Member
Posts: 151
Joined: 2002.09
Post: #5
i have this strange algorithm for applying 3 rotations on the rows of the canonial basis (here its on the columns and transposing at the end), i think i should try to simplify this sometime.

Code:
```column[0] = Vector3f(1,0,0); column[1] = Vector3f(0,1,0); column[2] = Vector3f(0,0,1); for(int i = 0 ; i < 3 ; i++) {     column[i] = Vector3f(             column[i].x,             cos(x)*column[i].y + sin(x)*column[i].z,             cos(x)*column[i].z - sin(x)*column[i].y );              column[i] = Vector3f(             cos(y)*column[i].x - sin(y)*column[i].z,             column[i].y,             cos(y)*column[i].z + sin(y)*column[i].x );                  column[i] = Vector3f(             cos(z)*column[i].x + sin(z)*column[i].y,             cos(z)*column[i].y - sin(z)*column[i].x,             column[i].z ); }     T();```
Puzzler183
Unregistered

Post: #6
I'd think that just concatenating 3 quaternions and then converting to a matrix would be the fastest way to do that. It would probably also be the fastest way to get angle axis. And it would be the fastest way to get a quaternion.
Member
Posts: 320
Joined: 2003.06
Post: #7
Thanks guys, this worked in the end. It does not need to be fast at this stage as it is only when called once per model at load time. (The matrix order is a bit funny because of the way ODE seems to need it)
David
Code:
```rotationMatrix[0] = cos(y) * cos(z);         rotationMatrix[4] = cos(y) * sin(z);         rotationMatrix[8] = -sin(y);         rotationMatrix[3] = 0;         rotationMatrix[1] = sin(x) * sin(y) * cos(z) + cos(x) * -sin(z);         rotationMatrix[5] = sin(x) * sin(y) * sin(z) + cos(x) * cos(z);         rotationMatrix[9] = sin(x) * cos(y);         rotationMatrix[7] = 0;         rotationMatrix[2] = cos(x) * sin(y) * cos(z) + sin(x) * sin(z);         rotationMatrix[6] = cos(x) * sin(y) * sin(z) + -sin(x) * cos(z);         rotationMatrix[10] = cos(x) * cos(y);         rotationMatrix[11] = 0;```

Chopper, iSight Screensavers, DuckDuckDuck: http://majicjungle.com
Puzzler183
Unregistered

Post: #8
One quick thing - since you use sin(x) and friends multiple times, you should just store them in temporary variables instead of recalculating. I know it doesn't need to be fast, but still...
Luminary
Posts: 5,143
Joined: 2002.04
Post: #9
Check the generated code first -- GCC should be "smart" enough to elide multiple identical calls to trig functions. Dunno if it really is though
kberg
Unregistered

Post: #10
Probably depends on the debugging level. I would actually hope that it doesn't at the -O0 level as that might cause confusion over line numbers. At -O2 I would really hope so!

In general I make it a practice to precalc and cache multiply used trig functions or inverses of denominators in code.
Puzzler183
Unregistered

Post: #11
Yeah, it should be.... I always just do it though because I don't know if GCC is smart enough and I work with other compilers. Not to mention how old habits die hard .