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 /* === T Y P E D E F S ===================================================== */
45 /* === C L A S S E S & S T R U C T S ======================================= */
49 // ========================================================================
50 /*! \class angle _angle.h ETL/angle
51 ** \brief Abstraction of the concept of an angle
52 ** \see angle::deg, angle::rad, angle::rot, angle::sin, angle::cos, angle::tan, fastangle
58 typedef float value_type;
61 typedef value_type unit;
63 unit v; //! Stored in radians; positive values indicate counter-clockwise.
68 ** Arithmetic Operators
72 operator+=(const angle &rhs)
73 { v+=rhs.v; return *this; }
76 operator-=(const angle &rhs)
77 { v-=rhs.v; return *this; }
80 operator*=(const unit &rhs)
81 { v*=rhs; return *this; }
84 operator/=(const unit &rhs)
85 { v/=rhs; return *this; }
87 //! Angle Addition Operator
89 operator+(const angle &rhs)const
90 { return angle(*this)+=rhs; }
92 //! Angle Subtraction Operator
93 /*! \sa angle dist(const angle &) */
95 operator-(const angle &rhs)const
96 { return angle(*this)-=rhs; }
98 //! Angle Scalar Multiplication Operator
99 /*! This operator will multiply the given
100 angle by the given scalar value. */
102 operator*(const unit &rhs)const
103 { return angle(*this)*=rhs; }
106 operator/(const unit &rhs)const
107 { return angle(*this)/=rhs; }
118 //! 180 degree rotation operator
119 /*! Returns the angle directly opposite of
120 the given angle, and will yield a result
130 /*! Returns true if the shortest
131 angle from the left-hand to the
132 right-hand side is counter-clockwise */
134 operator<(const angle &rhs)const
135 { return dist(rhs).v<(value_type)0.0; }
137 /*! Returns true if the shortest
138 angle from the left-hand to the
139 right-hand side is clockwise */
141 operator>(const angle &rhs)const
142 { return dist(rhs).v>(value_type)0.0; }
144 /*! Returns true if the shortest
145 angle from the left-hand to the
146 right-hand side is counter-clockwise,
147 or if the angles are refer to the same
148 point on the unit circle. */
150 operator<=(const angle &rhs)const
151 { return dist(rhs).v<=(value_type)0.0; }
153 /*! Returns true if the shortest
154 angle from the left-hand to the
155 right-hand side is clockwise,
156 or if the angles are refer to the same
157 point on the unit circle. */
159 operator>=(const angle &rhs)const
160 { return dist(rhs).v>=(value_type)0.0; }
162 /*! Returns true if the angles
163 are refer to the same point
164 on the unit circle. */
166 operator==(const angle &rhs)const
167 { return std::abs(dist(rhs).v)<epsilon; }
169 /*! Returns false if the angles
170 are refer to the same point
171 on the unit circle. */
173 operator!=(const angle &rhs)const
174 { return std::abs(dist(rhs).v)>epsilon; }
176 //! Angle Difference Function
177 /*! This function will return the
178 shortest physical distance between
179 two angles, from -PI/2 to PI/2
180 \sa angle operator-(const angle &) */
182 dist(const angle &rhs)const
186 ret.v-=rot_floor(ret.v+PI);
191 /*! This function will return the
192 value of the angle between 0 and 2PI */
197 ret.v-=rot_floor(ret.v);
201 //! Zero Rotation (0 degrees)
210 //! One Complete Rotation (360 degrees)
219 //! One Half Rotation (180 degrees)
228 bool operator!()const { return std::abs(mod().v) < epsilon; }
232 static value_type rot_floor(value_type x)
233 { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
235 static const value_type epsilon = 1.0e-6;
239 ** Conversion Classes
247 ** Trigonometric Classes
269 #ifndef ETL_NO_DEPRECATED
272 typedef rot rotations;
274 }; // END of class angle
276 // ========================================================================
277 /*! \class angle::rad _angle.h ETL/angle
278 ** \brief Angle representation in radians
282 class angle::rad : public angle
285 explicit rad(const value_type &x) { v=x; }
286 rad(const angle &a):angle(a) { }
287 rad mod()const { return angle::mod(); }
288 rad dist(const angle &rhs)const { return angle::dist(rhs); }
289 value_type get()const { return v; }
290 #ifndef ETL_NO_DEPRECATED
291 operator value_type()const ETL_DEPRECATED_FUNCTION;
293 }; // END of class angle::radians
294 inline angle::rad::operator angle::value_type()const { return get(); }
296 // ========================================================================
297 /*! \class angle::deg _angle.h ETL/angle
298 ** \brief Angle representation in degrees
302 class angle::deg : public angle
305 explicit deg(const value_type &x) { v=x*((PI*2)/360); }
306 deg(const angle &a):angle(a) { }
307 deg mod()const { return angle::mod(); }
308 deg dist(const angle &rhs)const { return angle::dist(rhs); }
309 value_type get()const { return v*360/(PI*2); }
310 #ifndef ETL_NO_DEPRECATED
311 operator value_type()const ETL_DEPRECATED_FUNCTION;
313 }; // END of class angle::degrees
314 inline angle::deg::operator angle::value_type()const { return get(); }
316 // ========================================================================
317 /*! \class angle::rot _angle.h ETL/angle
318 ** \brief Angle representation in rotations
322 class angle::rot : public angle
325 explicit rot(const value_type &x) { v=x*(PI*2); }
326 rot(const angle &a):angle(a) { }
327 rot mod()const { return angle::mod(); }
328 rot dist(const angle &rhs)const { return angle::dist(rhs); }
329 value_type get()const { return v/(PI*2); }
330 #ifndef ETL_NO_DEPRECATED
331 operator value_type()const ETL_DEPRECATED_FUNCTION;
333 }; // END of class angle::rotations
334 inline angle::rot::operator angle::value_type()const { return get(); }
336 // ========================================================================
337 /*! \class angle::sin _angle.h ETL/angle
338 ** \brief Angle representation as a sine function
342 class angle::sin : public angle
345 explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
346 sin(const angle &a):angle(a) { }
347 sin mod()const { return angle::mod(); }
348 sin dist(const angle &rhs)const { return angle::dist(rhs); }
349 value_type get()const { return static_cast<value_type>(std::sin(v)); }
350 #ifndef ETL_NO_DEPRECATED
351 operator value_type()const ETL_DEPRECATED_FUNCTION;
353 }; // END of class angle::sin
354 inline angle::sin::operator angle::value_type()const { return get(); }
356 // ========================================================================
357 /*! \class angle::cos _angle.h ETL/angle
358 ** \brief Angle representation as a cosine function
362 class angle::cos : public angle
365 explicit cos(const value_type &x) { v=(value_type)(std::acos(x)); }
366 cos(const angle &a):angle(a) { }
367 cos mod()const { return angle::mod(); }
368 cos dist(const angle &rhs)const { return angle::dist(rhs); }
369 value_type get()const { return (value_type)std::cos(v); }
370 #ifndef ETL_NO_DEPRECATED
371 operator value_type()const ETL_DEPRECATED_FUNCTION;
373 }; // END of class angle::cos
374 inline angle::cos::operator angle::value_type()const { return get(); }
376 // ========================================================================
377 /*! \class angle::tan _angle.h ETL/angle
378 ** \brief Angle representation as a tangent function
382 class angle::tan : public angle
385 explicit tan(const value_type &x) { v=(value_type)(std::atan(x)); }
386 tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
387 tan(const angle &a):angle(a) { }
388 tan mod()const { return angle::mod(); }
389 tan dist(const angle &rhs)const { return angle::dist(rhs); }
390 value_type get()const { return (value_type)std::tan(v); }
391 #ifndef ETL_NO_DEPRECATED
392 operator value_type()const ETL_DEPRECATED_FUNCTION;
394 }; // END of class angle::tan
395 inline angle::tan::operator angle::value_type()const { return get(); }
399 //#include <iostream>
401 template <typename T>
402 struct affine_combo<etl::angle, T>
406 //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
407 //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
409 etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
411 return b.dist(a)*(float)t+a;
414 etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
416 return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
421 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
423 etl::angle operator()(const etl::angle &a,const etl::angle &b)const
425 etl::angle delta=b.dist(a);
426 //if(delta<etl::angle::zero())
427 // return delta+etl::angle::one();
431 etl::angle cook(const etl::angle &x)const { return x; }
432 etl::angle uncook(const etl::angle &x)const { return x; }
435 /* === E N D =============================================================== */