Thanks. I tried it, and (after some translation for gcc) found that the
atan2 replacement has good accuracy but is little if any faster than
the library atan2.
double fast_atan2(double y, double x)
<snip>
Shaun Wexler
Blindingly fast! The maximum absolute error (>0.07 radians) is, alas,
much too big for my application.
Hmm. Looks fun, but I need float or double and that code is fixed point.
Here's another answer to my question, based on a 50-year old atan
approximation due to Hastings. It has |error| < 0.005, and (with all
relevant optimizations in gcc) is 3-5x faster than atan2 in spite of
two horrible divisions in the main code path.
#define PI_FLOAT 3.14159265f
#define PIBY2_FLOAT 1.5707963f
// |error| < 0.005
float fast_atan2f( float y, float x )
{
if ( x == 0.0f )
{
if ( y > 0.0f ) return PIBY2_FLOAT;
if ( y == 0.0f ) return 0.0f;
return -PIBY2_FLOAT;
}
float atan;
float z = y/x;
if ( fabsf( z ) < 1.0f )
{
atan = z/(1.0f + 0.28f*z*z);
if ( x < 0.0f )
{
if ( y < 0.0f ) return atan - PI_FLOAT;
return atan + PI_FLOAT;
}
}
else
{
atan = PIBY2_FLOAT - z/(z*z + 0.28f);
if ( y < 0.0f ) return atan - PI_FLOAT;
}
return atan;
}