Archived

This topic is now archived and is closed to further replies.

Glass_Knife

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

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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)

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites