Saturday, November 21, 2015

ATAN2Deg (int y, int x)

I'm using a floating point atan2 library, this is a bit expensive for a small processor.  Especially when everything I'm doing is in small integers and my output is a small integer degree.

So I did some research, and I found this site with a good approximation, but it had some minor bugs.

Integer Approximation of ATan2

I took that algorithm and created a small C# console app around it.

static int atan2deg(int y, int x)
{
{
    var max=Math.Max(y, x);
    if (max > 60)   // sqrt(2^15/3667)... avoid overflow 
        x = 60 * x / max;
        y = 60 * y / max; 
    }

    if (y==0)
        return (x>=0) ? 0 : 180;
            
    if (x==0)
        return (y>0) ? 90 : 270;

    int aX = Math.Abs(x);
    int aY = Math.Abs(y);

    int angle = (aY <= aX) ? 
        (3667 * aX * aY) / (64 * aX * aX + 17 * aY * aY) :
        90 - (3667 * aX * aY) / (64 * aY * aY + 17 * aX * aX);

    if (x<0)
        return (y<0) ? 180 + angle : 180 - angle;
    else
        return (y<0) ? 360-angle : angle;
}

The algorithm is quite accurate where it worked, but it had bugs;


  1. It wasn't written in a language I know, but appears similar to basic.  There where implied "else" clauses, that I filled-in
  2. The angle calculation needs to use the abs values of x and y, not the actual values
  3. The special case X = 0 and Y <= 0 outputs 270 not -90 as this is 001-360 based output
  4. Scaled input values to ensure we don't overflow 16-bit signed internal math


That said.. it is a very good algorithm

No comments:

Post a Comment