2 /* ========================================================================
3 ** Extended Template and Library
4 ** Angle Abstraction Class Implementation
7 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
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 =========================================================== */
31 /* === H E A D E R S ======================================================= */
36 /* === M A C R O S ========================================================= */
39 # define PI (3.1415926535897932384626433832795029L)
40 # define HALF_PI (PI/2)
43 #define ANGLE_EPSILON (1.0e-6)
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 // ========================================================================
52 /*! \class angle _angle.h ETL/angle
53 ** \brief Abstraction of the concept of an angle
54 ** \see angle::deg, angle::rad, angle::rot, angle::sin, angle::cos, angle::tan, fastangle
60 typedef float value_type;
63 typedef value_type unit;
65 unit v; //! Stored in radians; positive values indicate counter-clockwise.
70 ** Arithmetic Operators
74 operator+=(const angle &rhs)
75 { v+=rhs.v; return *this; }
78 operator-=(const angle &rhs)
79 { v-=rhs.v; return *this; }
82 operator*=(const unit &rhs)
83 { v*=rhs; return *this; }
86 operator/=(const unit &rhs)
87 { v/=rhs; return *this; }
89 //! Angle Addition Operator
91 operator+(const angle &rhs)const
92 { return angle(*this)+=rhs; }
94 //! Angle Subtraction Operator
95 /*! \sa angle dist(const angle &) */
97 operator-(const angle &rhs)const
98 { return angle(*this)-=rhs; }
100 //! Angle Scalar Multiplication Operator
101 /*! This operator will multiply the given
102 angle by the given scalar value. */
104 operator*(const unit &rhs)const
105 { return angle(*this)*=rhs; }
108 operator/(const unit &rhs)const
109 { return angle(*this)/=rhs; }
120 //! 180 degree rotation operator
121 /*! Returns the angle directly opposite of
122 the given angle, and will yield a result
132 /*! Returns true if the shortest
133 angle from the left-hand to the
134 right-hand side is counter-clockwise */
136 operator<(const angle &rhs)const
137 { return dist(rhs).v<(value_type)0.0; }
139 /*! Returns true if the shortest
140 angle from the left-hand to the
141 right-hand side is clockwise */
143 operator>(const angle &rhs)const
144 { return dist(rhs).v>(value_type)0.0; }
146 /*! Returns true if the shortest
147 angle from the left-hand to the
148 right-hand side is counter-clockwise,
149 or if the angles are refer to the same
150 point on the unit circle. */
152 operator<=(const angle &rhs)const
153 { return dist(rhs).v<=(value_type)0.0; }
155 /*! Returns true if the shortest
156 angle from the left-hand to the
157 right-hand side is clockwise,
158 or if the angles are refer to the same
159 point on the unit circle. */
161 operator>=(const angle &rhs)const
162 { return dist(rhs).v>=(value_type)0.0; }
164 /*! Returns true if the angles
165 are refer to the same point
166 on the unit circle. */
168 operator==(const angle &rhs)const
169 { return std::abs(dist(rhs).v)<ANGLE_EPSILON; }
171 /*! Returns false if the angles
172 are refer to the same point
173 on the unit circle. */
175 operator!=(const angle &rhs)const
176 { return std::abs(dist(rhs).v)>ANGLE_EPSILON; }
178 //! Absolute Angle Function
179 /*! This function will return the
180 absolute value of the angle. */
189 //! Angle Difference Function
190 /*! This function will return the
191 shortest physical distance between
192 two angles, from -PI/2 to PI/2
193 \sa angle operator-(const angle &) */
195 dist(const angle &rhs)const
199 ret.v-=rot_floor(ret.v+PI);
204 /*! This function will return the
205 value of the angle between 0 and 2PI */
210 ret.v-=rot_floor(ret.v);
214 //! Zero Rotation (0 degrees)
223 //! One Complete Rotation (360 degrees)
232 //! One Half Rotation (180 degrees)
241 bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; }
245 static value_type rot_floor(value_type x)
246 { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
250 ** Conversion Classes
258 ** Trigonometric Classes
280 #ifndef ETL_NO_DEPRECATED
283 typedef rot rotations;
285 }; // END of class angle
287 // ========================================================================
288 /*! \class angle::rad _angle.h ETL/angle
289 ** \brief Angle representation in radians
293 class angle::rad : public angle
296 explicit rad(const value_type &x) { v=x; }
297 rad(const angle &a):angle(a) { }
298 rad mod()const { return angle::mod(); }
299 rad dist(const angle &rhs)const { return angle::dist(rhs); }
300 value_type get()const { return v; }
301 #ifndef ETL_NO_DEPRECATED
302 // operator value_type()const ETL_DEPRECATED_FUNCTION;
304 }; // END of class angle::radians
305 // inline angle::rad::operator angle::value_type()const { return get(); }
307 // ========================================================================
308 /*! \class angle::deg _angle.h ETL/angle
309 ** \brief Angle representation in degrees
313 class angle::deg : public angle
316 explicit deg(const value_type &x) { v=x*((PI*2)/360); }
317 deg(const angle &a):angle(a) { }
318 deg mod()const { return angle::mod(); }
319 deg dist(const angle &rhs)const { return angle::dist(rhs); }
320 value_type get()const { return v*360/(PI*2); }
321 #ifndef ETL_NO_DEPRECATED
322 // operator value_type()const ETL_DEPRECATED_FUNCTION;
324 }; // END of class angle::degrees
325 // inline angle::deg::operator angle::value_type()const { return get(); }
327 // ========================================================================
328 /*! \class angle::rot _angle.h ETL/angle
329 ** \brief Angle representation in rotations
333 class angle::rot : public angle
336 explicit rot(const value_type &x) { v=x*(PI*2); }
337 rot(const angle &a):angle(a) { }
338 rot mod()const { return angle::mod(); }
339 rot dist(const angle &rhs)const { return angle::dist(rhs); }
340 value_type get()const { return v/(PI*2); }
341 #ifndef ETL_NO_DEPRECATED
342 // operator value_type()const ETL_DEPRECATED_FUNCTION;
344 }; // END of class angle::rotations
345 // inline angle::rot::operator angle::value_type()const { return get(); }
347 // ========================================================================
348 /*! \class angle::sin _angle.h ETL/angle
349 ** \brief Angle representation as a sine function
353 class angle::sin : public angle
356 explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
357 sin(const angle &a):angle(a) { }
358 sin mod()const { return angle::mod(); }
359 sin dist(const angle &rhs)const { return angle::dist(rhs); }
360 value_type get()const { return static_cast<value_type>(std::sin(v)); }
361 #ifndef ETL_NO_DEPRECATED
362 // operator value_type()const ETL_DEPRECATED_FUNCTION;
364 }; // END of class angle::sin
365 // inline angle::sin::operator angle::value_type()const { return get(); }
367 // ========================================================================
368 /*! \class angle::cos _angle.h ETL/angle
369 ** \brief Angle representation as a cosine function
373 class angle::cos : public angle
376 explicit cos(const value_type &x) { v=(value_type)(std::acos(x)); }
377 cos(const angle &a):angle(a) { }
378 cos mod()const { return angle::mod(); }
379 cos dist(const angle &rhs)const { return angle::dist(rhs); }
380 value_type get()const { return (value_type)std::cos(v); }
381 #ifndef ETL_NO_DEPRECATED
382 // operator value_type()const ETL_DEPRECATED_FUNCTION;
384 }; // END of class angle::cos
385 // inline angle::cos::operator angle::value_type()const { return get(); }
387 // ========================================================================
388 /*! \class angle::tan _angle.h ETL/angle
389 ** \brief Angle representation as a tangent function
393 class angle::tan : public angle
396 explicit tan(const value_type &x) { v=(value_type)(std::atan(x)); }
397 tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
398 tan(const angle &a):angle(a) { }
399 tan mod()const { return angle::mod(); }
400 tan dist(const angle &rhs)const { return angle::dist(rhs); }
401 value_type get()const { return (value_type)std::tan(v); }
402 #ifndef ETL_NO_DEPRECATED
403 // operator value_type()const ETL_DEPRECATED_FUNCTION;
405 }; // END of class angle::tan
406 // inline angle::tan::operator angle::value_type()const { return get(); }
410 //#include <iostream>
412 template <typename T>
413 struct affine_combo<etl::angle, T>
417 //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
418 //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
420 etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
422 return b.dist(a)*(float)t+a;
425 etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
427 return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
432 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
434 etl::angle operator()(const etl::angle &a,const etl::angle &b)const
436 etl::angle delta=b.dist(a);
437 //if(delta<etl::angle::zero())
438 // return delta+etl::angle::one();
442 etl::angle cook(const etl::angle &x)const { return x; }
443 etl::angle uncook(const etl::angle &x)const { return x; }
446 /* === E N D =============================================================== */