1 /* ========================================================================
2 ** Extended Template and Library
3 ** Angle Abstraction Class Implementation
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 ** Copyright (c) 2007 Chris Moore
9 ** This package is free software; you can redistribute it and/or
10 ** modify it under the terms of the GNU General Public License as
11 ** published by the Free Software Foundation; either version 2 of
12 ** the License, or (at your option) any later version.
14 ** This package is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ** General Public License for more details.
19 ** === N O T E S ===========================================================
21 ** This is an internal header file, included by other ETL headers.
22 ** You should not attempt to use it directly.
24 ** ========================================================================= */
26 /* === S T A R T =========================================================== */
28 #ifndef __ETL__ANGLE_H
29 #define __ETL__ANGLE_H
31 /* === H E A D E R S ======================================================= */
37 /* === M A C R O S ========================================================= */
40 # define PI (3.1415926535897932384626433832795029L)
41 # define HALF_PI (PI/2)
44 #define ANGLE_EPSILON (1.0e-6)
46 /* === T Y P E D E F S ===================================================== */
48 /* === C L A S S E S & S T R U C T S ======================================= */
52 // ========================================================================
53 /*! \class angle _angle.h ETL/angle
54 ** \brief Abstraction of the concept of an angle
55 ** \see angle::deg, angle::rad, angle::rot, angle::sin, angle::cos, angle::tan, fastangle
61 typedef float value_type;
64 typedef value_type unit;
66 unit v; //! Stored in radians; positive values indicate counter-clockwise.
71 ** Arithmetic Operators
75 operator+=(const angle &rhs)
76 { v+=rhs.v; return *this; }
79 operator-=(const angle &rhs)
80 { v-=rhs.v; return *this; }
83 operator*=(const unit &rhs)
84 { v*=rhs; return *this; }
87 operator/=(const unit &rhs)
88 { v/=rhs; return *this; }
90 //! Angle Addition Operator
92 operator+(const angle &rhs)const
93 { return angle(*this)+=rhs; }
95 //! Angle Subtraction Operator
96 /*! \sa angle dist(const angle &) */
98 operator-(const angle &rhs)const
99 { return angle(*this)-=rhs; }
101 //! Angle Scalar Multiplication Operator
102 /*! This operator will multiply the given
103 angle by the given scalar value. */
105 operator*(const unit &rhs)const
106 { return angle(*this)*=rhs; }
109 operator/(const unit &rhs)const
110 { return angle(*this)/=rhs; }
122 //! 180 degree rotation operator
123 /*! Returns the angle directly opposite of
124 the given angle, and will yield a result
133 #endif // ETL_NOT_USED
135 #ifdef ETL_WRAP_ANGLES
136 /*! Returns true if the shortest
137 angle from the left-hand to the
138 right-hand side is counter-clockwise */
140 operator<(const angle &rhs)const
141 { return dist(rhs).v<(value_type)0.0; }
143 /*! Returns true if the shortest
144 angle from the left-hand to the
145 right-hand side is clockwise */
147 operator>(const angle &rhs)const
148 { return dist(rhs).v>(value_type)0.0; }
150 /*! Returns true if the shortest
151 angle from the left-hand to the
152 right-hand side is counter-clockwise,
153 or if the angles are refer to the same
154 point on the unit circle. */
156 operator<=(const angle &rhs)const
157 { return dist(rhs).v<=(value_type)0.0; }
159 /*! Returns true if the shortest
160 angle from the left-hand to the
161 right-hand side is clockwise,
162 or if the angles are refer to the same
163 point on the unit circle. */
165 operator>=(const angle &rhs)const
166 { return dist(rhs).v>=(value_type)0.0; }
168 /*! Returns true if the angles
169 are refer to the same point
170 on the unit circle. */
172 operator==(const angle &rhs)const
173 { return std::abs(dist(rhs).v)<ANGLE_EPSILON; }
175 /*! Returns false if the angles
176 are refer to the same point
177 on the unit circle. */
179 operator!=(const angle &rhs)const
180 { return std::abs(dist(rhs).v)>ANGLE_EPSILON; }
181 #else // ETL_WRAP_ANGLES
182 /*! Returns true if the left-hand
183 side is less than the
186 operator<(const angle &rhs)const
187 { return v < rhs.v; }
189 /*! Returns true if the left-hand
190 side is greater than the
193 operator>(const angle &rhs)const
194 { return v > rhs.v; }
196 /*! Returns true if the left-hand
197 side is less or equal to the
200 operator<=(const angle &rhs)const
201 { return v <= rhs.v; }
203 /*! Returns true if the left-hand
204 side is greater than or equal
205 to the right-hand side */
207 operator>=(const angle &rhs)const
208 { return v >= rhs.v; }
210 /*! Returns true if the angles
211 are the same, or close */
213 operator==(const angle &rhs)const
214 { return std::abs(v - rhs.v)<ANGLE_EPSILON; }
216 /*! Returns false if the angles
219 operator!=(const angle &rhs)const
220 { return std::abs(v - rhs.v)>ANGLE_EPSILON; }
221 #endif // ETL_WRAP_ANGLES
223 //! Absolute Angle Function
224 /*! This function will return the
225 absolute value of the angle. */
234 #ifdef ETL_WRAP_ANGLES
235 //! Angle Difference Function
236 /*! This function will return the
237 shortest physical distance between
238 two angles, from -PI/2 to PI/2
239 \sa angle operator-(const angle &) */
241 dist(const angle &rhs)const
245 ret.v-=rot_floor(ret.v+PI);
250 /*! This function will return the
251 value of the angle between 0 and 2PI */
256 ret.v-=rot_floor(ret.v);
259 #else // ETL_WRAP_ANGLES
260 //! Angle Difference Function
261 /*! This function will return the
263 two angles, just like
264 \sa angle operator-(const angle &) */
266 dist(const angle &rhs)const
267 { return angle(*this)-=rhs; }
270 /*! This function will return the
271 value of the angle */
278 #endif // ETL_WRAP_ANGLES
280 //! Zero Rotation (0 degrees)
289 //! One Complete Rotation (360 degrees)
298 //! One Half Rotation (180 degrees)
307 bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; }
311 #ifdef ETL_WRAP_ANGLES
312 static value_type rot_floor(value_type x)
313 { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
314 #endif // ETL_WRAP_ANGLES
318 ** Conversion Classes
326 ** Trigonometric Classes
348 #ifndef ETL_NO_DEPRECATED
351 typedef rot rotations;
353 }; // END of class angle
355 // ========================================================================
356 /*! \class angle::rad _angle.h ETL/angle
357 ** \brief Angle representation in radians
361 class angle::rad : public angle
364 explicit rad(const value_type &x) { v=x; }
365 rad(const angle &a):angle(a) { }
366 rad mod()const { return angle::mod(); }
367 rad dist(const angle &rhs)const { return angle::dist(rhs); }
368 value_type get()const { return v; }
369 #ifndef ETL_NO_DEPRECATED
370 // operator value_type()const ETL_DEPRECATED_FUNCTION;
372 }; // END of class angle::radians
373 // inline angle::rad::operator angle::value_type()const { return get(); }
375 // ========================================================================
376 /*! \class angle::deg _angle.h ETL/angle
377 ** \brief Angle representation in degrees
381 class angle::deg : public angle
384 explicit deg(const value_type &x) { v=x*((PI*2)/360); }
385 deg(const angle &a):angle(a) { }
386 deg mod()const { return angle::mod(); }
387 deg dist(const angle &rhs)const { return angle::dist(rhs); }
388 value_type get()const { return v*360/(PI*2); }
389 #ifndef ETL_NO_DEPRECATED
390 // operator value_type()const ETL_DEPRECATED_FUNCTION;
392 }; // END of class angle::degrees
393 // inline angle::deg::operator angle::value_type()const { return get(); }
395 // ========================================================================
396 /*! \class angle::rot _angle.h ETL/angle
397 ** \brief Angle representation in rotations
401 class angle::rot : public angle
404 explicit rot(const value_type &x) { v=x*(PI*2); }
405 rot(const angle &a):angle(a) { }
406 rot mod()const { return angle::mod(); }
407 rot dist(const angle &rhs)const { return angle::dist(rhs); }
408 value_type get()const { return v/(PI*2); }
409 #ifndef ETL_NO_DEPRECATED
410 // operator value_type()const ETL_DEPRECATED_FUNCTION;
412 }; // END of class angle::rotations
413 // inline angle::rot::operator angle::value_type()const { return get(); }
415 // ========================================================================
416 /*! \class angle::sin _angle.h ETL/angle
417 ** \brief Angle representation as a sine function
421 class angle::sin : public angle
424 explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
425 sin(const angle &a):angle(a) { }
426 sin mod()const { return angle::mod(); }
427 sin dist(const angle &rhs)const { return angle::dist(rhs); }
428 value_type get()const { return static_cast<value_type>(std::sin(v)); }
429 #ifndef ETL_NO_DEPRECATED
430 // operator value_type()const ETL_DEPRECATED_FUNCTION;
432 }; // END of class angle::sin
433 // inline angle::sin::operator angle::value_type()const { return get(); }
435 // ========================================================================
436 /*! \class angle::cos _angle.h ETL/angle
437 ** \brief Angle representation as a cosine function
441 class angle::cos : public angle
444 explicit cos(const value_type &x) { v=(value_type)(std::acos(x)); }
445 cos(const angle &a):angle(a) { }
446 cos mod()const { return angle::mod(); }
447 cos dist(const angle &rhs)const { return angle::dist(rhs); }
448 value_type get()const { return (value_type)std::cos(v); }
449 #ifndef ETL_NO_DEPRECATED
450 // operator value_type()const ETL_DEPRECATED_FUNCTION;
452 }; // END of class angle::cos
453 // inline angle::cos::operator angle::value_type()const { return get(); }
455 // ========================================================================
456 /*! \class angle::tan _angle.h ETL/angle
457 ** \brief Angle representation as a tangent function
461 class angle::tan : public angle
464 explicit tan(const value_type &x) { v=(value_type)(std::atan(x)); }
465 tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
466 tan(const angle &a):angle(a) { }
467 tan mod()const { return angle::mod(); }
468 tan dist(const angle &rhs)const { return angle::dist(rhs); }
469 value_type get()const { return (value_type)std::tan(v); }
470 #ifndef ETL_NO_DEPRECATED
471 // operator value_type()const ETL_DEPRECATED_FUNCTION;
473 }; // END of class angle::tan
474 // inline angle::tan::operator angle::value_type()const { return get(); }
478 //#include <iostream>
480 template <typename T>
481 struct affine_combo<etl::angle, T>
485 //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
486 //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
488 etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
490 return b.dist(a)*(float)t+a;
493 etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
495 return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
500 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
502 etl::angle operator()(const etl::angle &a,const etl::angle &b)const
504 etl::angle delta=b.dist(a);
505 //if(delta<etl::angle::zero())
506 // return delta+etl::angle::one();
510 etl::angle cook(const etl::angle &x)const { return x; }
511 etl::angle uncook(const etl::angle &x)const { return x; }
514 /* === E N D =============================================================== */