 /*=-=-=-=-=-=-=-=-=-=-  RCCL/RCI Notice of Copyright  -=-=-=-=-=-=-=-=-=-=-=*
 *									    *
 *	Copyright (C) 1987 by all authors described below. Permission to    *
 *	use, distribute and copy is granted, but only for non-commercial    *
 *	purposes and providing the authors are acknowledged and this 	    *
 *	copyright notice is displayed prominently.			    *
 *									    *
 *	The authors provide this software in hope that it will be useful,   *
 *	but do not assume responsibility for its use.			    *
 *									    *
 *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

/*=~=~=~=~ McGill-Computer-Vision-and-Robotics-Laboratory--C-Module ~=~=~=~=
 *		
 * MODULE NAME:	atan.c
 *
 * DESCRIPTION:	Contains code for the table driven ATAN2() routines.
 * 
 * AUTHOR/DATE:	John Lloyd, Fall 1986
 *
 *~=~=~=~=~=~= McGill-Computer-Vision-and-Robotics-Laboratory ~=~=~=~=~=~=*/

#include <math.h>
#include "ctabledefs.h"

#define PI2  6.28318530718
#define PID2 1.57079632679
#define PI   3.14159265359

float ATAN2 (y, x)
double y, x;
{
	register struct _tabent *atp;
	register int index;
	double r;

	if (x == 0.0 && y == 0.0)
	 { return (0.0);
	 }

	/* octants are labelled 1 to 8, counter clockwise from the +X axis */

	if (y >= 0.)			/* top half */
	 { if (x >= 0.)
	    { if (x >= y)		/* octant 1, take y over x */
	       { 
		 index = (r = ATAN2_TSCALE * (y/x));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( atp->a * r + atp->b );	
	       }
	      else			/* octant 2, take x over y */
	       {
		 index = (r = ATAN2_TSCALE * (x/y));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( PID2 - (atp->a * r + atp->b) );
	       }
	    }
	   else
	    { if (y >= -x)		/* octant 3, take -x over y */
	       {
		 index = (r = ATAN2_TSCALE * (x/y));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( PID2 - (atp->a * r + atp->b) );
	       }
	      else			/* octant 4, take y over -x */
	       {
		 index = (r = ATAN2_TSCALE * (y/x));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( PI + (atp->a * r + atp->b) );
	       }
	    }
	 }
	else
	 { if (x < 0.)
	    { if (-x >= -y)		/* octant 5, take -y over -x */
	       {
		 index = (r = ATAN2_TSCALE * (y/x));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( -PI + (atp->a * r + atp->b) );
	       }
	      else			/* octant 6, take -x over -y */
	       {
		 index = (r = ATAN2_TSCALE * (x/y));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( -PID2 - (atp->a * r + atp->b) );
	       }
	    }
	   else
	    { if (-y >= x)		/* octant 7, take x over -y */
	       {
		 index = (r = ATAN2_TSCALE * (x/y));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return ( -PID2 - (atp->a * r + atp->b) );
	       }
	      else			/* octant 8, take -y over x */
	       {
		 index = (r = ATAN2_TSCALE * (y/x));
		 atp = &mt_atan2 [ index+ATAN2_TORIGIN ];
		 r -= index;
		 return (atp->a * r + atp->b);
	       }
	    }
	 }
}
