Re: need help with mathematics... rotation
# Re: need help with mathematics... rotation

**Subject**: **Re: need help with mathematics... rotation**
- From: K Payne <email@hidden>
- Date: Sun, 05 Aug 2001 23:29:55 -0600
- User-agent: Microsoft-Outlook-Express-Macintosh-Edition/5.02.2022

....

>

* i am implementing the controls of a ship, and i need help with :*
>

* - a rotation around a line but not around an axis. For exemple when my*
>

* ship's direction is on the z, x plane, to turn right or left i do a*
>

* rotation around the y axis. To do so i multiply my ship direction by a*
>

* matrix of the type*
>

* Ry(x)=( 1 0 0 0*
>

* 0 cosx -sinx 0*
>

* 0 sinx cosx 0*
>

* 0 0 0 1 );*
>

* *
>

* but a ship also goes up and down, and so when my direction is ( 0, 1,*
>

* 0 ) i.e. the ship is going along the Y+ axis that rotation(Ry(x)) will be*
>

* useless. So what i though of would be to make my rotation around an Up*
>

* vector which would be perpendicular to my direction. I think it should*
>

* work but i don't know how to do a rotation other than along the x, y, or z*
>

* axis and i would need to do it along that Up Vector.*
>

* *
>

* Could someone help me a bit here, that is my last step to finally having*
>

* my ship to fly around in a 3D world !*
>

* *
.....

This is pretty much the same as Joe Ante's reply with code contributed

from Erich Boleyn, except it isn't the standard reversal of operation style

akin to matrix multiplication. I think it helps to see it from another point

of view (no pun intended :D)

Having somewhat of physics and math background, I do all my own

rotations for my objects and camera positions and orientations from scratch.

Here's the deal:

I first define a orientation with 3 vectors; forward, up and right. The

minimum requirement world only be 2 since the 3 can always be found using a

cross product, but it's simpler to have the 3 at all times.

So far (in code)..

GLfloat forward [] = {0. , 0. , 1.};

GLfloat up [] = {0. , 1. , 0.};

GLfloat right [] = {1. , 0. , 0.}; // = forward CROSS up

Notice that they all are perpendicular. Now with this set up you can

rotate the orientation on any of these (the orientations) axis/vectors

without any possibility of gimble lock. Here's how to do it....

First define a function that takes two vectors (hopefully perpendicular) and

rotates both of these vectors, through a given angle, in the plane they

define in space. If you want to rotate about the forward axis (z only at the

very beginning!!!) you would pass the function the up and right vectors. The

axis of rotation isn't passed to it since it's not effected and also not

needed. In this example I imagine the first vector being the x axis and the

second as the y axis of a standard 2d situation. This doesn't matter in the

end but it helps visualize it.

void RotateOnPlane (GLfloat *v1, GLfloat *v2, float radians)

{

GLfloat sn,cs;

GLfloat temp [3];

// save the first vector

temp [0] = v1[0];

temp [1] = v1[1];

temp [2] = v1[2];

sn = sin (radians);

cs = cos (radians);

/* rotate the first vector (the new vector is a linear combination of

the original two) */

v1[0] = (v1[0] * cs) + (v2[0] * sn);

v1[1] = (v1[1] * cs) + (v2[1] * sn);

v1[2] = (v1[2] * cs) + (v2[2] * sn);

/* rotate the 2nd vector using the original two vectors (not the new v1)

*/

v2[0] = (v2[0] * cs) + (temp[0] * (- sn));

v2[1] = (v2[1] * cs) + (temp[0] * (- sn));

v2[2] = (v2[2] * cs) + (temp[0] * (- sn));

}

So if you want to rotate about the forward vector (a roll for airplanes) you

would do this:

RotateOnPlane (right, up, anlge_in_radians);

or for an airplane style pitch (pulling up or diving down):

RotateOnPlane (up, forward, anlge_in_radians);

...Yaw should be obvious now...

and to set up the scene:

gluLookAt ( ship.x,

ship.y,

ship.z,

ship.x + forward[0],

ship.y + forward[1],

ship.z + forward[2],

up[0],

up[1],

up[2] );

This approach my not be the in terms of efficientcy, since the gluLookAt

function has the sqrt ( 1 - z^2 ) operations in it. This redoes the undoing

of matrix operation reversal. But the penalty is VERY small and I think the

added intuitiveness of this style far outweighs the redundant operations. If

anyone has any comments please feel free to do so.

Kenneth (Kiff) Payne