PDA

View Full Version : How can I take reverse of tan() ? (Extracting angles from velocity)...



BigShooter
10-20-2003, 05:05 PM
Hi, I ahve run into a minor problem programming a simple asteroid game in open gl.
I have an Object class (in C++) that holds vectors for acceleration, velocity, position and a double for rotation.
What I would like to do is have the object rotate to its velocity.
For instance, if velocity is v(1,1) the ship would be rotated 45 degrees (the game is 2d so rotation happens on the z axis).
The rotation and translation is defined as follows:
glTranslated(position.x, position.y, 0.0);
glRotated(rotation, 0.0, 0.0, 1.0);

There's also a limit on the velocity and when player presses a button, the acceleration increases, and then is decreased a bit each frame (causing acceleration and drag to the ship movement).

The problem I ran into is extracting the rotation value...

If I set theta = the angle between x axis and velocity vector, I could extract it as follows (correct me if I'm wrong):

tan theta = opposite/adjacent // these are lenths of the x, y components of the vector.

The problem is that I can't find a cotangent function is c or c++ that would take the invesre of tangent to get me the theta...

I guess I could also get the angles by using angle cosines, but if I have cos theta = x/ |velocity| but then I have to have a cosecant (spelling?) csc? function... which I also can't find it.... reverses for sin,cos,tan are in my calculator... aren't there any in C++ ?

Thank you for the help....

guest
10-20-2003, 06:36 PM
Look up atan(), acos, and asin. For c++, they come from the math.h standard library. All functions return angles in radians I think.

10-23-2003, 08:01 AM
Another good one is

radians = atan2(y, x);

This works for most any combination of y and x, including the cases when one or both are zero and one or more is infinity. (But not in the case where one is not-a-number.)

atan2(y,x) is therefore better than atan(y/x) because
* atan2 knows what quadrant you are in, while atan assumes that you are always in the right side of the origin.
* atan2 doesn't have divide-by-zero problems when y != 0 and x == 0
* atan2 doens't have Not-a-Number problems when both x and y == 0, or both x and y == infinity.

0 radians is pointing along +x axis. +radians is a movement in the CounterClockwise(CCW) direction. To convert this to normal compass directions (+y, CW, never negative), use the formula degrees = (int)(360.5 + 90 - 180 * radians / M_PI ) % 360;


Special note to graphics persons:
If you are trying to rotate a directional pointer in the direction of momement based on delta-x and delta-y, then you should handing the 0,0 case specially, because even though atan2 returns an answer, it might not be the answer you want.
Example:
Target is 5.37 meters at bearing 230 degrees
Target is 2.52 meters at bearing 225 degrees
Target is 0.03 meters at bearing 043 degrees
Target is 0.00 meters at bearing 0 degrees.
(The last lines makes little sense as the bearing can abruptly changes as two points get close together if they are not staying on the same mathematically perfect line. It is better in some applications to use branching logic.
epsilon = 0.30;
if ( distance <= epsilon ) {
#display round dot
printf("Target is here!\n");
} else {
#rotate radians
#display arrow
printf("Target is %lf meters at bearing %03d degrees\n", distance, degrees);
}

-Richard Penner

BigShooter
10-23-2003, 12:03 PM
Thank you Richard,
Luke

10-26-2003, 08:06 AM
Originally posted by BigShooter:
Thank you Richard,
Luke

10-26-2003, 08:37 AM
...