3 * Copyright 2005 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
23 #include <gr_math.h> // declaration is in here
28 /***************************************************************************/
29 /* Constant definitions */
30 /***************************************************************************/
32 #define TAN_MAP_RES 0.003921569 /* (smallest non-zero value in table) */
33 #define RAD_PER_DEG 0.017453293
34 #define TAN_MAP_SIZE 256
36 /* arctangents from 0 to pi/4 radians */
38 fast_atan_table[257] = {
39 0.000000e+00, 3.921549e-03, 7.842976e-03, 1.176416e-02,
40 1.568499e-02, 1.960533e-02, 2.352507e-02, 2.744409e-02,
41 3.136226e-02, 3.527947e-02, 3.919560e-02, 4.311053e-02,
42 4.702413e-02, 5.093629e-02, 5.484690e-02, 5.875582e-02,
43 6.266295e-02, 6.656816e-02, 7.047134e-02, 7.437238e-02,
44 7.827114e-02, 8.216752e-02, 8.606141e-02, 8.995267e-02,
45 9.384121e-02, 9.772691e-02, 1.016096e-01, 1.054893e-01,
46 1.093658e-01, 1.132390e-01, 1.171087e-01, 1.209750e-01,
47 1.248376e-01, 1.286965e-01, 1.325515e-01, 1.364026e-01,
48 1.402496e-01, 1.440924e-01, 1.479310e-01, 1.517652e-01,
49 1.555948e-01, 1.594199e-01, 1.632403e-01, 1.670559e-01,
50 1.708665e-01, 1.746722e-01, 1.784728e-01, 1.822681e-01,
51 1.860582e-01, 1.898428e-01, 1.936220e-01, 1.973956e-01,
52 2.011634e-01, 2.049255e-01, 2.086818e-01, 2.124320e-01,
53 2.161762e-01, 2.199143e-01, 2.236461e-01, 2.273716e-01,
54 2.310907e-01, 2.348033e-01, 2.385093e-01, 2.422086e-01,
55 2.459012e-01, 2.495869e-01, 2.532658e-01, 2.569376e-01,
56 2.606024e-01, 2.642600e-01, 2.679104e-01, 2.715535e-01,
57 2.751892e-01, 2.788175e-01, 2.824383e-01, 2.860514e-01,
58 2.896569e-01, 2.932547e-01, 2.968447e-01, 3.004268e-01,
59 3.040009e-01, 3.075671e-01, 3.111252e-01, 3.146752e-01,
60 3.182170e-01, 3.217506e-01, 3.252758e-01, 3.287927e-01,
61 3.323012e-01, 3.358012e-01, 3.392926e-01, 3.427755e-01,
62 3.462497e-01, 3.497153e-01, 3.531721e-01, 3.566201e-01,
63 3.600593e-01, 3.634896e-01, 3.669110e-01, 3.703234e-01,
64 3.737268e-01, 3.771211e-01, 3.805064e-01, 3.838825e-01,
65 3.872494e-01, 3.906070e-01, 3.939555e-01, 3.972946e-01,
66 4.006244e-01, 4.039448e-01, 4.072558e-01, 4.105574e-01,
67 4.138496e-01, 4.171322e-01, 4.204054e-01, 4.236689e-01,
68 4.269229e-01, 4.301673e-01, 4.334021e-01, 4.366272e-01,
69 4.398426e-01, 4.430483e-01, 4.462443e-01, 4.494306e-01,
70 4.526070e-01, 4.557738e-01, 4.589307e-01, 4.620778e-01,
71 4.652150e-01, 4.683424e-01, 4.714600e-01, 4.745676e-01,
72 4.776654e-01, 4.807532e-01, 4.838312e-01, 4.868992e-01,
73 4.899573e-01, 4.930055e-01, 4.960437e-01, 4.990719e-01,
74 5.020902e-01, 5.050985e-01, 5.080968e-01, 5.110852e-01,
75 5.140636e-01, 5.170320e-01, 5.199904e-01, 5.229388e-01,
76 5.258772e-01, 5.288056e-01, 5.317241e-01, 5.346325e-01,
77 5.375310e-01, 5.404195e-01, 5.432980e-01, 5.461666e-01,
78 5.490251e-01, 5.518738e-01, 5.547124e-01, 5.575411e-01,
79 5.603599e-01, 5.631687e-01, 5.659676e-01, 5.687566e-01,
80 5.715357e-01, 5.743048e-01, 5.770641e-01, 5.798135e-01,
81 5.825531e-01, 5.852828e-01, 5.880026e-01, 5.907126e-01,
82 5.934128e-01, 5.961032e-01, 5.987839e-01, 6.014547e-01,
83 6.041158e-01, 6.067672e-01, 6.094088e-01, 6.120407e-01,
84 6.146630e-01, 6.172755e-01, 6.198784e-01, 6.224717e-01,
85 6.250554e-01, 6.276294e-01, 6.301939e-01, 6.327488e-01,
86 6.352942e-01, 6.378301e-01, 6.403565e-01, 6.428734e-01,
87 6.453808e-01, 6.478788e-01, 6.503674e-01, 6.528466e-01,
88 6.553165e-01, 6.577770e-01, 6.602282e-01, 6.626701e-01,
89 6.651027e-01, 6.675261e-01, 6.699402e-01, 6.723452e-01,
90 6.747409e-01, 6.771276e-01, 6.795051e-01, 6.818735e-01,
91 6.842328e-01, 6.865831e-01, 6.889244e-01, 6.912567e-01,
92 6.935800e-01, 6.958943e-01, 6.981998e-01, 7.004964e-01,
93 7.027841e-01, 7.050630e-01, 7.073330e-01, 7.095943e-01,
94 7.118469e-01, 7.140907e-01, 7.163258e-01, 7.185523e-01,
95 7.207701e-01, 7.229794e-01, 7.251800e-01, 7.273721e-01,
96 7.295557e-01, 7.317307e-01, 7.338974e-01, 7.360555e-01,
97 7.382053e-01, 7.403467e-01, 7.424797e-01, 7.446045e-01,
98 7.467209e-01, 7.488291e-01, 7.509291e-01, 7.530208e-01,
99 7.551044e-01, 7.571798e-01, 7.592472e-01, 7.613064e-01,
100 7.633576e-01, 7.654008e-01, 7.674360e-01, 7.694633e-01,
101 7.714826e-01, 7.734940e-01, 7.754975e-01, 7.774932e-01,
102 7.794811e-01, 7.814612e-01, 7.834335e-01, 7.853983e-01,
107 /*****************************************************************************
108 Function: Arc tangent
110 Syntax: angle = fast_atan2(y, x);
111 REAL y y component of input vector
112 REAL x x component of input vector
113 REAL angle angle of vector (x, y) in radians
115 Description: This function calculates the angle of the vector (x,y) based
116 on a table lookup and linear interpolation. The table uses
117 a 256 point table covering -45 to +45 degrees and uses
118 symetry to determine the final angle value in the range of
119 -180 to 180 degrees. Note that this function uses the small
120 angle approximation for values close to zero. This routine
121 calculates the arc tangent with an average error of
123 *****************************************************************************/
126 gr_fast_atan2f(REAL y, REAL x)
128 REAL x_abs, y_abs, z;
129 REAL alpha, angle, base_angle;
132 /* don't divide by zero! */ // FIXME could get hosed with -0.0
133 if ((y == 0.0) && (x == 0.0))
136 /* normalize to +/- 45 degree range */
139 //z = (y_abs < x_abs ? y_abs / x_abs : x_abs / y_abs);
145 /* when ratio approaches the table resolution, the angle is */
146 /* best approximated with the argument itself... */
150 /* find index and interpolation value */
151 alpha = z * (REAL) TAN_MAP_SIZE - .5;
153 alpha -= (REAL) index;
154 /* determine base angle based on quadrant and */
155 /* add or subtract table value from base angle based on quadrant */
156 base_angle = fast_atan_table[index];
158 (fast_atan_table[index + 1] - fast_atan_table[index]) * alpha;
161 if (x_abs > y_abs) { /* -45 -> 45 or 135 -> 225 */
162 if (x >= 0.0) { /* -45 -> 45 */
164 angle = base_angle; /* 0 -> 45, angle OK */
166 angle = -base_angle; /* -45 -> 0, angle = -angle */
167 } else { /* 135 -> 180 or 180 -> -135 */
168 angle = 3.14159265358979323846;
170 angle -= base_angle; /* 135 -> 180, angle = 180 - angle */
172 angle = base_angle - angle; /* 180 -> -135, angle = angle - 180 */
174 } else { /* 45 -> 135 or -135 -> -45 */
175 if (y >= 0.0) { /* 45 -> 135 */
176 angle = 1.57079632679489661923;
178 angle -= base_angle; /* 45 -> 90, angle = 90 - angle */
180 angle += base_angle; /* 90 -> 135, angle = 90 + angle */
181 } else { /* -135 -> -45 */
182 angle = -1.57079632679489661923;
184 angle += base_angle; /* -90 -> -45, angle = -90 + angle */
186 angle -= base_angle; /* -135 -> -90, angle = -90 - angle */
192 return (angle + TWOPI);