1 /*! ========================================================================
2 ** Extended Template and Library
3 ** Fast fastangle Abstraction Class Implementation
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
8 ** This package is free software; you can redistribute it and/or
9 ** modify it under the terms of the GNU General Public License as
10 ** published by the Free Software Foundation; either version 2 of
11 ** the License, or (at your option) any later version.
13 ** This package is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ** General Public License for more details.
18 ** === N O T E S ===========================================================
20 ** This is an internal header file, included by other ETL headers.
21 ** You should not attempt to use it directly.
23 ** ========================================================================= */
25 /* === S T A R T =========================================================== */
27 #ifndef __ETL_FASTANGLE_H
28 #define __ETL_FASTANGLE_H
30 /* === H E A D E R S ======================================================= */
35 #include "_fastangle_tables.h"
37 /* === M A C R O S ========================================================= */
40 # define PI (3.1415926535897932384626433832795029L)
43 #define ETL_FASTANGLE_INIT()
45 /* === T Y P E D E F S ===================================================== */
47 /* === C L A S S E S & S T R U C T S ======================================= */
51 /*! ========================================================================
53 ** \brief Optimized abstraction of the concept of an angle
55 ** A more detailed description needs to be written.
60 typedef double value_type;
63 typedef fixed_base<ETL_FIXED_TYPE,ETL_FASTANGLE_LOOKUP_RES> unit;
65 unit v; //! Stored in rotations
70 ** Arithmetic Operators
73 //! fastangle Addition Operator
75 operator+(const fastangle &rhs)const
82 //! fastangle Subtraction Operator
83 /*! \sa fastangle dist(const fastangle &) */
85 operator-(const fastangle &rhs)const
92 //! fastangle Scalar Multiplication Operator
93 /*! This operator will multiply the given
94 fastangle by the given scalar value. */
96 operator*(const unit &rhs)const
104 operator/(const unit &rhs)const
112 operator+=(const fastangle &rhs)
119 operator-=(const fastangle &rhs)
126 operator*=(const unit &rhs)
133 operator/=(const unit &rhs)
139 //! fastangle Negation
148 //! 180 degree rotation operator
149 /*! Returns the fastangle directly opposite of
150 the given fastangle, and will yield a result
156 ret.v=(unit)std::floor(v+0.5f);
160 /*! Returns true if the shortest
161 fastangle between the left-hand and
162 right-hand side is clockwise */
164 operator<(const fastangle &rhs)const
166 // { return dist(rhs).v<(value_type)0.0; }
168 /*! Returns true if the shortest
169 fastangle between the left-hand and
170 right-hand side is counter-clockwise */
172 operator>(const fastangle &rhs)const
174 // { return dist(rhs).v>(value_type)0.0; }
176 /*! Returns true if the shortest
177 fastangle between the left-hand and
178 right-hand side is clockwise,
179 or if the angles are refer to the same
180 point on the unit circle. */
182 operator<=(const fastangle &rhs)const
184 // { return dist(rhs).v<=(value_type)0.0; }
186 /*! Returns true if the shortest
187 fastangle between the left-hand and
188 right-hand side is counter-clockwise,
189 or if the angles are refer to the same
190 point on the unit circle. */
192 operator>=(const fastangle &rhs)const
194 // { return dist(rhs).v>=(value_type)0.0; }
196 /*! Returns true if the angles
197 are refer to the same point
198 on the unit circle. */
200 operator==(const fastangle &rhs)const
202 // { return dist(rhs).v==(value_type)0.0; }
204 /*! Returns false if the angles
205 are refer to the same point
206 on the unit circle. */
208 operator!=(const fastangle &rhs)const
210 // { return dist(rhs).v!=(value_type)0.0; }
212 //! fastangle Difference Function
213 /*! This function will return the
214 shortest physical distance between
215 two angles, from -PI/2 to PI/2
216 \warning Not yet tested
217 \sa fastangle operator-(const fastangle &) */
219 dist(const fastangle &rhs)const
223 ret.v-=(unit)std::floor(ret.v+0.5f);
228 /*! This function will return the
229 value of the fastangle between 0 and 2PI */
233 fastangle ret(*this);
234 ret.v-=(unit)std::floor(ret.v);
246 bool operator!()const { return v==unit(0); }
249 ** Conversion Classes
257 ** Trigonometric Classes
268 friend class radians;
269 friend class degrees;
270 friend class rotations;
281 typedef rotations rot;
283 }; // END of class fastangle
285 /*! ========================================================================
286 ** \class fastangle::radians
287 ** \brief fastangle representation in radians
289 ** A more detailed description needs to be written.
291 class fastangle::radians : public fastangle
294 radians(const value_type &x) { v=x/((value_type)PI*2.0f); }
295 radians(const fastangle &a):fastangle(a) { }
296 radians mod()const { return fastangle::mod(); }
297 radians dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
298 operator value_type()const { return get(); }
299 value_type get()const { return (value_type)v*(value_type)PI*2.0f; }
300 }; // END of class fastangle::radians
302 /*! ========================================================================
303 ** \class fastangle::degrees
304 ** \brief fastangle representation in degrees
306 ** A more detailed description needs to be written.
308 class fastangle::degrees : public fastangle
311 degrees(const value_type &x) { v=x/360; }
312 degrees(const fastangle &a):fastangle(a) { }
313 degrees mod()const { return fastangle::mod(); }
314 degrees dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
315 operator value_type()const { return get(); }
316 value_type get()const { return v*360/*(value_type)(v-::floor(v))*360*/; }
317 }; // END of class fastangle::degrees
319 /*! ========================================================================
320 ** \class fastangle::rotations
321 ** \brief fastangle representation in rotations
323 ** A more detailed description needs to be written.
325 class fastangle::rotations : public fastangle
328 rotations(const value_type &x) { v=x; }
329 rotations(const fastangle &a):fastangle(a) { }
330 rotations mod()const { return fastangle::mod(); }
331 rotations dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
332 operator value_type()const { return get(); }
333 value_type get()const { return v; }
334 }; // END of class fastangle::rotations
336 /*! ========================================================================
337 ** \class fastangle::sin
338 ** \brief fastangle representation as a sine function
340 ** A more detailed description needs to be written.
342 class fastangle::sin : public fastangle
345 sin(const value_type &x) { v.data()=_fastangle_asin_table[(int)((x+1)*(value_type)(1<<(ETL_FASTANGLE_LOOKUP_RES-1)))]; }
346 sin(const fastangle &a):fastangle(a) { }
347 sin mod()const { return fastangle::mod(); }
348 sin dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
349 operator value_type()const { return get(); }
350 value_type get()const { return (value_type)_fastangle_sin_table[v.data()&( (1<<ETL_FASTANGLE_LOOKUP_RES)-1)]; }
351 }; // END of class fastangle::sin
353 /*! ========================================================================
354 ** \class fastangle::cos
355 ** \brief fastangle representation as a cosine function
357 ** A more detailed description needs to be written.
359 class fastangle::cos : public fastangle
362 cos(const value_type &x) { v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_asin_table[(int)((x+1)*(value_type)(1<<(ETL_FASTANGLE_LOOKUP_RES-1)))]; }
363 cos(const fastangle &a):fastangle(a) { }
364 cos mod()const { return fastangle::mod(); }
365 cos dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
366 operator value_type()const { return get(); }
367 value_type get()const { return (value_type)_fastangle_sin_table[(v.data()+(1<<(ETL_FASTANGLE_LOOKUP_RES-2)))&( (1<<ETL_FASTANGLE_LOOKUP_RES)-1)]; }
368 }; // END of class fastangle::cos
370 /*! ========================================================================
371 ** \class fastangle::tan
372 ** \brief fastangle representation as a tangent function
374 ** A more detailed description needs to be written.
376 class fastangle::tan : public fastangle
379 tan(const value_type &x)
382 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((1.0/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
384 v.data()=-(1<<(ETL_FASTANGLE_LOOKUP_RES-1)) + (1<<(ETL_FASTANGLE_LOOKUP_RES-2)) - _fastangle_atan_table[(int)(((1.0/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
386 v.data()=_fastangle_atan_table[(int)((x+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
389 tan(const value_type &y,const value_type &x)
391 if(x>=0 && y>=0) // First quadrant
394 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
396 v.data()=_fastangle_atan_table[(int)(((y/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
398 else if(x>=0 && y<0) // Fourth quadrant
401 v.data()=-(1<<(ETL_FASTANGLE_LOOKUP_RES-1)) + (1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
403 v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
405 else if(x<0 && y>=0) // Second quadrant
408 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
410 v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]+(1<<(ETL_FASTANGLE_LOOKUP_RES-1));
412 else if(x<0 && y<0) // Third Quadrant
415 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))] - (1<<(ETL_FASTANGLE_LOOKUP_RES-1));
417 v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]-(1<<(ETL_FASTANGLE_LOOKUP_RES-1));
421 tan(const fastangle &a):fastangle(a) { }
422 tan mod()const { return fastangle::mod(); }
423 tan dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
424 operator value_type()const { return get(); }
425 value_type get()const { return (value_type)_fastangle_tan_table[v.data()&( (1<<ETL_FASTANGLE_LOOKUP_RES)-1)]; }
426 }; // END of class fastangle::tan
431 struct affine_combo<etl::fastangle,float>
433 etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b,const float &t)const
435 return b.dist(a)*t+a;
438 etl::fastangle reverse(const etl::fastangle &x, const etl::fastangle &b, const float &t)const
440 return x.dist(b*t)*((float)1/((float)1-t));
445 struct distance_func<etl::fastangle> : public std::binary_function<etl::fastangle, etl::fastangle, etl::fastangle>
447 etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b)const
449 etl::fastangle delta=b.dist(a);
450 if(delta<etl::fastangle::zero())
455 etl::fastangle cook(const etl::fastangle &x) { return x; }
456 etl::fastangle uncook(const etl::fastangle &x) { return x; }
459 /* === E N D =============================================================== */