rotations in 3d space

Hi, I’m trying to write my own rotation code to handle rotation of my own vector structure. I got the mathematical transformations on the internet, and came up with these three functions:

void rot_x(vec_p a, GLfloat r)
a->y = a->ycos® - a->zsin®;
a->z = a->ysin® + a->zcos®;
a->x = a->x;

void rot_y(vec_p a, GLfloat r)
a->z = a->zcos® - a->xsin®;
a->x = a->zsin® + a->xcos®;
a->y = a->y;

void rot_z(vec_p a, GLfloat r)
a->x = a->xcos® - a->ysin®;
a->y = a->xsin® + a->ycos®;
a->z = a->z;

where vec is structure of {GLfloat x, y, z}.

These seem to work, the problem is, after many rotations the vectors seem to “lose their shape”…they become shorter and shorter until they no longer have any magnitude. It’s almost as if they “lose” a bit of vector on every rotation, cumulatively adding up to a decrease in size. Does anyone know what this is caused by? I thought it might be innaccuracy caused by using GLfloat instead of doubles, or something in the sine/cosine functions. Any fix would be greatly appreciated.

I don’t know why the functions don’t work, they look ok to me (I have not checked the Euler rotation matrix so there might be a mathematical error). Try multiplying your vectors (vertices) by a single orthogonal rotation matrix. This way you will only need one function for every possible rotation.

You could also try using polar coordinate vectors for your rotations. These preserve the length of a vector very well (it is always constant) but you will need functions for polar-rectangular and vice-versa conversions.

My ultimate advice would be to use quaternions. I have had many problems with Euler methods and switching to quaternion methods made my life 10 times better.

Hope this helps…


You’re making a classic mistake. Take rot_x as an example. To calculate a->z, you need a->y, but you’re modifying a->y on the line above. a->y is no longer the same value you pass to the function. Solution: make a copy of the vector you pass to the function and use that instead when calculating new values.

right…thanks Bob that was the problem.

Thanks a lot