ETL  0.04.19
_angle.h
Go to the documentation of this file.
1 /* ========================================================================
2 ** Extended Template and Library
3 ** Angle Abstraction Class Implementation
4 ** $Id$
5 **
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
7 ** Copyright (c) 2007 Chris Moore
8 **
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.
13 **
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.
18 **
19 ** === N O T E S ===========================================================
20 **
21 ** This is an internal header file, included by other ETL headers.
22 ** You should not attempt to use it directly.
23 **
24 ** ========================================================================= */
25 
26 /* === S T A R T =========================================================== */
27 
28 #ifndef __ETL__ANGLE_H
29 #define __ETL__ANGLE_H
30 
31 /* === H E A D E R S ======================================================= */
32 
33 #include <cstdio>
34 #include <cmath>
35 #include <functional>
36 
37 /* === M A C R O S ========================================================= */
38 
39 #ifndef PI
40 # define PI (3.1415926535897932384626433832795029L)
41 # define HALF_PI (PI/2)
42 #endif
43 
44 #define ANGLE_EPSILON (1.0e-6)
45 
46 /* === T Y P E D E F S ===================================================== */
47 
48 /* === C L A S S E S & S T R U C T S ======================================= */
49 
51 
52 // ========================================================================
58 class angle
59 {
60 public:
61  typedef float value_type;
62 
63 protected:
64  typedef value_type unit;
65 
66  unit v;
67 
68 public:
69 
70  /*
71  ** Arithmetic Operators
72  */
73 
74  const angle &
75  operator+=(const angle &rhs)
76  { v+=rhs.v; return *this; }
77 
78  const angle &
79  operator-=(const angle &rhs)
80  { v-=rhs.v; return *this; }
81 
82  const angle &
83  operator*=(const unit &rhs)
84  { v*=rhs; return *this; }
85 
86  const angle &
87  operator/=(const unit &rhs)
88  { v/=rhs; return *this; }
89 
91  angle
92  operator+(const angle &rhs)const
93  { return angle(*this)+=rhs; }
94 
96 
97  angle
98  operator-(const angle &rhs)const
99  { return angle(*this)-=rhs; }
100 
102 
104  angle
105  operator*(const unit &rhs)const
106  { return angle(*this)*=rhs; }
107 
108  angle
109  operator/(const unit &rhs)const
110  { return angle(*this)/=rhs; }
111 
113  angle
114  operator-()const
115  {
116  angle ret;
117  ret.v=-v;
118  return ret;
119  }
120 
121 #ifdef ETL_NOT_USED
122 
123 
126  angle
127  operator~()const
128  {
129  angle ret;
130  ret.v = v+PI;
131  return ret.mod();
132  }
133 #endif // ETL_NOT_USED
134 
135 #ifdef ETL_WRAP_ANGLES
136 
139  bool
140  operator<(const angle &rhs)const
141  { return dist(rhs).v<(value_type)0.0; }
142 
146  bool
147  operator>(const angle &rhs)const
148  { return dist(rhs).v>(value_type)0.0; }
149 
155  bool
156  operator<=(const angle &rhs)const
157  { return dist(rhs).v<=(value_type)0.0; }
158 
164  bool
165  operator>=(const angle &rhs)const
166  { return dist(rhs).v>=(value_type)0.0; }
167 
171  bool
172  operator==(const angle &rhs)const
173  { return std::abs(dist(rhs).v)<ANGLE_EPSILON; }
174 
178  bool
179  operator!=(const angle &rhs)const
180  { return std::abs(dist(rhs).v)>ANGLE_EPSILON; }
181 #else // ETL_WRAP_ANGLES
182 
185  bool
186  operator<(const angle &rhs)const
187  { return v < rhs.v; }
188 
192  bool
193  operator>(const angle &rhs)const
194  { return v > rhs.v; }
195 
199  bool
200  operator<=(const angle &rhs)const
201  { return v <= rhs.v; }
202 
206  bool
207  operator>=(const angle &rhs)const
208  { return v >= rhs.v; }
209 
212  bool
213  operator==(const angle &rhs)const
214  { return std::abs(v - rhs.v)<ANGLE_EPSILON; }
215 
218  bool
219  operator!=(const angle &rhs)const
220  { return std::abs(v - rhs.v)>ANGLE_EPSILON; }
221 #endif // ETL_WRAP_ANGLES
222 
224 
226  angle
227  abs()const
228  {
229  angle ret;
230  ret.v=std::abs(v);
231  return ret;
232  }
233 
234 #ifdef ETL_WRAP_ANGLES
235 
236 
240  angle
241  dist(const angle &rhs)const
242  {
243  angle ret;
244  ret.v=v-rhs.v;
245  ret.v-=rot_floor(ret.v+PI);
246  return ret;
247  }
248 
250 
252  angle
253  mod()const
254  {
255  angle ret(*this);
256  ret.v-=rot_floor(ret.v);
257  return ret;
258  }
259 #else // ETL_WRAP_ANGLES
260 
261 
265  angle
266  dist(const angle &rhs)const
267  { return angle(*this)-=rhs; }
268 
270 
272  angle
273  mod()const
274  {
275  angle ret(*this);
276  return ret;
277  }
278 #endif // ETL_WRAP_ANGLES
279 
281  static angle
283  {
284  angle ret;
285  ret.v=0;
286  return ret;
287  }
288 
290  static angle
291  one()
292  {
293  angle ret;
294  ret.v=PI*2;
295  return ret;
296  }
297 
299  static angle
301  {
302  angle ret;
303  ret.v=PI;
304  return ret;
305  }
306 
307  bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; }
308 
309 private:
310 
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
315 
316 public:
317  /*
318  ** Conversion Classes
319  */
320 
321  class rad;
322  class deg;
323  class rot;
324 
325  /*
326  ** Trigonometric Classes
327  */
328 
329  class sin;
330  class cos;
331  class tan;
332 
333  /*
334  ** Friend classes
335  */
336 
337  friend class rad;
338  friend class deg;
339  friend class rot;
340  friend class sin;
341  friend class cos;
342  friend class tan;
343 
344  /*
345  ** Deprecated
346  */
347 
348 #ifndef ETL_NO_DEPRECATED
349  typedef rad radians;
350  typedef deg degrees;
351  typedef rot rotations;
352 #endif
353 }; // END of class angle
354 
355 // ========================================================================
361 class angle::rad : public angle
362 {
363 public:
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;
371 #endif
372 }; // END of class angle::radians
373 // inline angle::rad::operator angle::value_type()const { return get(); }
374 
375 // ========================================================================
381 class angle::deg : public angle
382 {
383 public:
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;
391 #endif
392 }; // END of class angle::degrees
393 // inline angle::deg::operator angle::value_type()const { return get(); }
394 
395 // ========================================================================
401 class angle::rot : public angle
402 {
403 public:
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;
411 #endif
412 }; // END of class angle::rotations
413 // inline angle::rot::operator angle::value_type()const { return get(); }
414 
415 // ========================================================================
421 class angle::sin : public angle
422 {
423 public:
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;
431 #endif
432 }; // END of class angle::sin
433 // inline angle::sin::operator angle::value_type()const { return get(); }
434 
435 // ========================================================================
441 class angle::cos : public angle
442 {
443 public:
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;
451 #endif
452 }; // END of class angle::cos
453 // inline angle::cos::operator angle::value_type()const { return get(); }
454 
455 // ========================================================================
461 class angle::tan : public angle
462 {
463 public:
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;
472 #endif
473 }; // END of class angle::tan
474 // inline angle::tan::operator angle::value_type()const { return get(); }
475 
477 
478 //#include <iostream>
479 
480 template <typename T>
481 struct affine_combo<etl::angle, T>
482 {
483  typedef T time_type;
484 
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; }
487 
488  etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
489  {
490  return b.dist(a)*(float)t+a;
491  }
492 
493  etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
494  {
495  return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
496  }
497 };
498 
499 template <>
500 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
501 {
502  etl::angle operator()(const etl::angle &a,const etl::angle &b)const
503  {
504  etl::angle delta=b.dist(a);
505  //if(delta<etl::angle::zero())
506  // return delta+etl::angle::one();
507  return delta;
508  }
509 
510  etl::angle cook(const etl::angle &x)const { return x; }
511  etl::angle uncook(const etl::angle &x)const { return x; }
512 };
513 
514 /* === E N D =============================================================== */
515 
516 #endif