arctan2.h

Go to the documentation of this file.
00001 /*
00002  * SpanDSP - a series of DSP components for telephony
00003  *
00004  * arctan2.h - A quick rough approximate arc tan
00005  *
00006  * Written by Steve Underwood <steveu@coppice.org>
00007  *
00008  * Copyright (C) 2003 Steve Underwood
00009  *
00010  * All rights reserved.
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 2.1,
00014  * as published by the Free Software Foundation.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00024  *
00025  * $Id: arctan2.h,v 1.13 2008/05/29 13:04:19 steveu Exp $
00026  */
00027 
00028 /*! \file */
00029 
00030 #if !defined(_SPANDSP_ARCTAN2_H_)
00031 #define _SPANDSP_ARCTAN2_H_
00032 
00033 /*! \page arctan2_page Fast approximate four quadrant arc-tangent
00034 \section arctan2_page_sec_1 What does it do?
00035 This module provides a fast approximate 4-quadrant arc tangent function,
00036 based on something at dspguru.com. The worst case error is about 4.07 degrees.
00037 This is fine for many "where am I" type evaluations in comms. work.
00038 
00039 \section arctan2_page_sec_2 How does it work?
00040 ???.
00041 */
00042 
00043 #if defined(__cplusplus)
00044 extern "C"
00045 {
00046 #endif
00047 
00048 /* This returns its answer as a signed 32 bit integer phase value. */
00049 static __inline__ int32_t arctan2(float y, float x)
00050 {
00051     float abs_y;
00052     float angle;
00053 
00054     if (x == 0.0f  ||  y == 0.0f)
00055         return 0;
00056     
00057     abs_y = fabsf(y);
00058 
00059     /* If we are in quadrant II or III, flip things around */
00060     if (x < 0.0f)
00061         angle = 3.0f - (x + abs_y)/(abs_y - x);
00062     else
00063         angle = 1.0f - (x - abs_y)/(abs_y + x);
00064     angle *= 536870912.0f;
00065 
00066     /* If we are in quadrant III or IV, negate to return an
00067        answer in the range +-pi */
00068     if (y < 0.0f)
00069         angle = -angle;
00070     return (int32_t) angle;
00071 }
00072 /*- End of function --------------------------------------------------------*/
00073 
00074 #if 0
00075 /* This returns its answer in radians, in the range +-pi. */
00076 static __inline__ float arctan2f(float y, float x)
00077 {
00078     float angle;
00079     float fx;
00080     float fy;
00081 
00082     if (x == 0.0f  ||  y == 0.0f)
00083         return 0;
00084     fx = fabsf(x);
00085     fy = fabsf(y);
00086     /* Deal with the octants */
00087     /* N.B. 0.28125 == (1/4 + 1/32) */
00088     if (fy > fx)
00089         angle = 3.1415926f/2.0f - fx*fy/(y*y + 0.28125f*x*x);
00090     else
00091         angle = fy*fx/(x*x + 0.28125f*y*y);
00092     
00093     /* Deal with the quadrants, to bring the final answer to the range +-pi */
00094     if (x < 0.0f)
00095         angle = 3.1415926f - angle;
00096     if (y < 0.0f)
00097         angle = -angle;
00098     return angle;
00099 }
00100 /*- End of function --------------------------------------------------------*/
00101 #endif
00102 
00103 #if defined(__cplusplus)
00104 }
00105 #endif
00106 
00107 #endif
00108 /*- End of file ------------------------------------------------------------*/

Generated on Tue Oct 7 20:25:45 2008 for spandsp by  doxygen 1.5.6