c / c++ atan2( ) bug???

Started by
6 comments, last by Glass_Knife 20 years, 9 months ago
I am curently having a problem understanding the outcome of the c++ function double atan2( double y, double x ). I have been doing some testing with it, and I do not understand the results I get back. I don''t know if this is a bug or I just don''t understand it. Here is the test code I''m running...

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
    double val1 = atan2(  0.0,  0.0 );
    double val2 = atan2( -0.0,  0.0 );
    double val3 = atan2(  0.0, -0.0 );
    double val4 = atan2( -0.0, -0.0 );

    double val5 = atan2(  0.000000001, 0.0 );
    double val6 = atan2( -0.000000001, 0.0 );
    double val7 = atan2(  0.0,         0.000000001 );
    double val8 = atan2(  0.0,        -0.000000001 );

    cout << val1 << endl
	 << val2 << endl
	 << val3 << endl
	 << val4 << endl
	 << val5 << endl
	 << val6 << endl
	 << val7 << endl
	 << val8 << endl;

    return 0;
}
The results... 0 0 0 0 1.5708 -1.5708 0 3.14159 The first set all returns zero, but the second set does not. I would consider 0.000000001 close enough to zero that I should be getting number back that might not be exacly zero, but close. Converting the numbers to degrees gives me 180 and 90, not 0. I thought maybe 0.000000001 was not close enough to zero, but I even tried it with 1.0E-160 and got the same results. Can anyone explain why this is? Glass_Knife I think, therfore I am. I think?

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Advertisement
atan2(0,0) produces undefined results. You should never count on the result of atan2(0,0) (with a magnitude of 0, there''s no way to determine the actual angle.)

How appropriate. You fight like a cow.
quote:Original post by Sneftel
atan2(0,0) produces undefined results.


atan2(0,0) does not produce undefined results. That''s the whole point of the function, to catch divide by zero errors. The data returned from all the (0.0,0.0) class is correct, it''s the data where the number is almost zero that is wrong.

atan2()

Glass_Knife



I think, therfore I am.
I think?

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Uh, there is nothing wrong with your results, that is the expected output of atan2.
(the output isn''t close to zero just because the input is close to zero, it''s ANGLES we''re talking about)
atan2(y,x) returns the angle relative to 0 degrees.
I think the function output is correct.
For atan2(0.000001,0.0) you go up a miniscule amount on the Y-axis and 0 units in the X direction. So this line is straight up and the angle from 0 to this line is PI / 2 or 90 degrees.

Similar reasoning can be applied to the rest of your results. Also changing the magnitude of the small number should make no difference in these particular set of coordinates. As in the case above, you should get PI / 2 for both:
atan2(0.0000001,0.0) and atan2(1.0,0.0).
A few things:

1. atan2 is NOT to prevent 0/0, only x/0. If you''re sticking in two 0''s to atan2, you already have real problems.

2. atan2 (x, 0) will produce nonzero results if x is not equal to 0. That''s how it should work. The function is doing the best it can to determine the angle of a vector with a VERY small magnitude, and getting it correct.

3. What the heck are you really trying to do here? Under what circumstances would you pass two 0, or close-to-0, numbers into atan2?

How appropriate. You fight like a cow.
quote:Original post by Sneftel
3. What the heck are you really trying to do here? Under what circumstances would you pass two 0, or close-to-0, numbers into atan2?


I am converting from a 3D point to a Spherical 2 angle and distance. Then converting back. I am using the atan2() to figure out the angles for the Spherical representation. But I want the results to convert correclty even it the point is (0,2,0). In this case the azimuth angle = atan2( z, x ) or atan2(0,0). Straight up on the y axis. But if I am going to use the angles for opengl rotations, then there is a big difference between 0 180 degrees.
Point3f p;Cylindrical3f c;Spherical3f s( 0.0f, toRadians(-90.0f), 2.0f );p.set( &s );p.get( &c );cout << c.toString() << endl;


This is how my game math library is set up. But right now, after I pass a Spherical3f to set the point, and then pull out Cylindrical3f, it has changes the azimuth angle from 0 to -180.



I think, therfore I am.
I think?

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

In the case you mentioned, the result of atan2() doesn''t matter, since gimbal lock kicks in. The results upon converting back to a vector will be the same, assuming you programmed it correctly.

How appropriate. You fight like a cow.

This topic is closed to new replies.

Advertisement