BALL  1.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
angle.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 #ifndef BALL_MATHS_ANGLE_H
6 #define BALL_MATHS_ANGLE_H
7 
8 #ifndef BALL_COMMON_EXCEPTION_H
9 # include <BALL/COMMON/exception.h>
10 #endif
11 
12 #ifndef BALL_COMMON_DEBUG_H
13 # include <BALL/COMMON/debug.h>
14 #endif
15 
16 #ifndef BALL_COMMON_CREATE_H
17 # include <BALL/COMMON/create.h>
18 #endif
19 
20 #ifndef BALL_MATHS_COMMON_H
21 # include <BALL/MATHS/common.h>
22 #endif
23 
24 namespace BALL
25 {
31  template <typename T>
32  class TAngle;
33 
34  template <typename T>
36  TAngle<T> operator * (const T& val, const TAngle<T>& angle);
37 
38  template <typename T>
40  TAngle<T> operator + (const T& val, const TAngle<T>& angle);
41 
42  template <typename T>
44  TAngle<T> operator - (const T& val, const TAngle<T>& angle);
45 
51  template <typename T>
52  class TAngle
53  {
54  public:
55 
57 
58 
61 
67  enum Range
68  {
69  // no limitations
71  // 0 <= angle <= 360, 0 <= angle <= (Constants::PI * 2)
73  // -180 <= angle <= 180, -Constants::PI <= angle <= Constants::PI
75  };
77 
80 
84  TAngle();
85 
91  TAngle(const TAngle& angle);
92 
100  explicit TAngle(const T& new_value, bool radian = true);
101 
104  virtual ~TAngle()
105  {
106  }
107 
111  virtual void clear()
112  {
113  value = (T)0;
114  }
116 
120 
123  void swap(TAngle& angle);
124 
131  void set(const T& new_value, bool radian = true);
132 
136  void set(const TAngle& angle);
137 
140  TAngle& operator = (const TAngle& angle);
141 
147  TAngle& operator = (const T& new_value);
148 
152  void get(TAngle& angle) const;
153 
158  void get(T& val, bool radian = true) const;
159 
161 
164 
168  operator T () const;
169 
173  T toRadian() const
174  ;
175 
180  static T toRadian(const T& degree);
181 
185  T toDegree() const;
186 
191  static T toDegree(const T& radian);
192 
199  void normalize(Range range);
200 
203  void negate();
204 
207  TAngle operator + () const;
208 
211  TAngle operator - () const;
212 
217  TAngle& operator += (const TAngle& angle);
218 
223  TAngle& operator += (const T& val);
224 
229  TAngle operator + (const TAngle& angle);
230 
235  TAngle& operator -= (const TAngle& angle);
236 
241  TAngle& operator -= (const T& val);
242 
247  TAngle operator - (const TAngle& angle);
248 
253  TAngle& operator *= (const TAngle& angle);
254 
259  TAngle& operator *= (const T& val);
260 
266  TAngle& operator /= (const TAngle& angle);
267 
273  TAngle& operator /= (const T& val);
274 
280  TAngle operator / (const TAngle& val);
281 
283 
286 
293  bool operator == (const TAngle& angle) const;
294 
301  bool operator != (const TAngle& angle) const;
302 
309  bool operator < (const TAngle& angle) const;
310 
317  bool operator < (const T& val) const;
318 
325  bool operator <= (const TAngle& angle) const;
326 
333  bool operator >= (const TAngle& angle) const;
334 
341  bool operator > (const TAngle& angle) const;
342 
349  bool isEquivalent(TAngle angle) const;
350 
352 
355 
360  bool isValid () const;
361 
368  void dump(std::ostream& s = std::cout, Size depth = 0) const;
369 
371 
374 
377  T value;
378 
380  };
382 
383  template <typename T>
385  : value((T)0)
386  {
387  }
388 
389  template <typename T>
390  TAngle<T>::TAngle(const TAngle& angle)
391  : value((T)angle.value)
392  {
393  }
394 
395  template <typename T>
396  TAngle<T>::TAngle(const T& new_value, bool radian)
397  : value((radian == true)
398  ? (T)new_value
399  : (T)BALL_ANGLE_DEGREE_TO_RADIAN((double)new_value))
400  {
401  }
402 
403  template <typename T>
404  void TAngle<T>::swap(TAngle& angle)
405  {
406  T temp = value;
407  value = angle.value;
408  angle.value = temp;
409  }
410 
411  template <typename T>
412  void TAngle<T>::set(const TAngle& angle)
413  {
414  value = angle.value;
415  }
416 
417  template <typename T>
418  void TAngle<T>::set(const T& new_value, bool radian)
419  {
420  value = (radian == true)
421  ? new_value
422  : BALL_ANGLE_DEGREE_TO_RADIAN(new_value);
423  }
424 
425  template <typename T>
427  {
428  value = angle.value;
429  return *this;
430  }
431 
432  template <typename T>
433  TAngle<T>& TAngle<T>::operator = (const T& new_value)
434  {
435  value = new_value;
436  return *this;
437  }
438 
439  template <typename T>
440  void TAngle<T>::get(TAngle& angle) const
441  {
442  angle.value = value;
443  }
444 
445  template <typename T>
446  void TAngle<T>::get(T& val, bool radian) const
447  {
448  val = (radian == true)
449  ? value
451  }
452 
453  template <typename T>
455  {
456  return value;
457  }
458 
459  template <typename T>
461  {
462  return value;
463  }
464 
465  template <typename T>
466  T TAngle<T>::toRadian(const T& degree)
467  {
468  return BALL_ANGLE_DEGREE_TO_RADIAN(degree);
469  }
470 
471  template <typename T>
473  {
474  if (value == (T) 0.0) return (T) 0.0;
475  return BALL_ANGLE_RADIAN_TO_DEGREE(value);
476  }
477 
478  template <typename T>
479  T TAngle<T>::toDegree(const T& radian)
480  {
481  if (radian == (T) 0.0) return (T) 0.0;
482  return BALL_ANGLE_RADIAN_TO_DEGREE(radian);
483  }
484 
485  template <typename T>
487  {
488  if (range == RANGE__UNLIMITED)
489  {
490  return;
491  }
492 
493  long mod_factor = (long)(value / (2 * Constants::PI));
494  value -= mod_factor * (Constants::PI * 2);
495 
496  while (Maths::isGreater(value, (Constants::PI * 2)))
497  {
498  value -= (Constants::PI * 2);
499  }
500  while (Maths::isLess(value, -(Constants::PI * 2)))
501  {
502  value += (Constants::PI * 2);
503  }
504  if (range == RANGE__SIGNED) // invariant: -180 to 180:
505  {
506  if (Maths::isGreater(value, Constants::PI))
507  {
508  value -= (Constants::PI * 2);
509  }
510  }
511  else
512  { // invariant: 0 to 360:
513  if (Maths::isLess(value, 0))
514  {
515  value += (Constants::PI * 2);
516  }
517  }
518  }
519 
520  template <typename T>
522  {
523  value = -value;
524  }
525 
526  template <typename T>
528  {
529  return *this;
530  }
531 
532  template <typename T>
534  {
535  return TAngle(-value);
536  }
537 
538  template <typename T>
540  {
541  value += angle.value;
542  return *this;
543  }
544 
545  template <typename T>
547  {
548  value += val;
549  return *this;
550  }
551 
552  template <typename T>
554  {
555  return TAngle(value + angle.value);
556  }
557 
558  template <typename T>
560  {
561  value -= angle.value;
562  return *this;
563  }
564 
565  template <typename T>
567  {
568  value -= val;
569  return *this;
570  }
571 
572  template <typename T>
574  {
575  return TAngle(value - angle.value);
576  }
577 
578  template <typename T>
580  {
581  value *= angle.value;
582  return *this;
583  }
584 
585  template <typename T>
587  {
588  value *= val;
589  return *this;
590  }
591 
592  template <typename T>
594  {
595  if (angle.value == 0)
596  {
597  throw Exception::DivisionByZero(__FILE__, __LINE__);
598  }
599  value /= angle.value;
600  return *this;
601  }
602 
603 
604  template <typename T>
606  {
607  if (val == 0)
608  {
609  throw Exception::DivisionByZero(__FILE__, __LINE__);
610  }
611 
612  value /= val;
613  return *this;
614  }
615 
616 
617  template <typename T>
619  {
620  if (val.value == 0)
621  {
622  throw Exception::DivisionByZero(__FILE__, __LINE__);
623  }
624 
625  return TAngle(value / val.value);
626  }
627 
628  template <typename T>
629  bool TAngle<T>::operator == (const TAngle& angle) const
630  {
631  return Maths::isEqual(value, angle.value);
632  }
633 
634  template <typename T>
635  bool TAngle<T>::operator != (const TAngle& angle) const
636  {
637  return Maths::isNotEqual(value, angle.value);
638  }
639 
640  template <typename T>
641  bool TAngle<T>::operator < (const TAngle& angle) const
642  {
643  return Maths::isLess(value, angle.value);
644  }
645 
646  template <typename T>
647  bool TAngle<T>::operator < (const T& val) const
648  {
649  return Maths::isLess(value, val);
650  }
651 
652  template <typename T>
653  bool TAngle<T>::operator <= (const TAngle& angle) const
654  {
655  return Maths::isLessOrEqual(value, angle.value);
656  }
657 
658  template <typename T>
659  bool TAngle<T>::operator >= (const TAngle& angle) const
660  {
661  return Maths::isGreaterOrEqual(value, angle.value);
662  }
663 
664  template <typename T>
665  bool TAngle<T>::operator > (const TAngle& angle) const
666 
667  {
668  return Maths::isGreater(value, angle.value);
669  }
670 
671  template <typename T>
672  bool TAngle<T>::isEquivalent(TAngle angle) const
673  {
674  TAngle this_angle(*this);
675 
676  this_angle.normalize(RANGE__UNSIGNED);
677  angle.normalize(RANGE__UNSIGNED);
678 
679  return (this_angle == angle);
680  }
681 
682  template <typename T>
683  bool TAngle<T>::isValid() const
684  {
685  return true;
686  }
687 
688  template <typename T>
689  void TAngle<T>::dump(std::ostream& s, Size depth) const
690  {
692 
693  BALL_DUMP_HEADER(s, this, this);
694 
695  BALL_DUMP_DEPTH(s, depth);
696  s << " value: " << value << std::endl;
697 
699  }
700 
706 
710  template <typename T>
712  TAngle<T> operator * (const T& val, const TAngle<T>& angle)
713  {
714  return TAngle<T>(val * angle.value);
715  }
716 
720  template <typename T>
722  TAngle<T> operator + (const T& val, const TAngle<T>& angle)
723  {
724  return TAngle<T>(val + angle.value);
725  }
726 
730  template <typename T>
732  TAngle<T> operator - (const T& val, const TAngle<T>& angle)
733  {
734  return TAngle<T>(val - angle.value);
735  }
736 
740  template <typename T>
741  std::istream& operator >> (std::istream& s, TAngle<T>& angle)
742  {
743  char c;
744  s >> c >> angle.value >> c;
745  return s;
746  }
747 
753  template <typename T>
754  std::ostream& operator << (std::ostream& s, const TAngle<T>& angle)
755  {
756  s << '(' << angle.value << ')';
757 
758  return s;
759  }
760 
761 } // namespace BALL
762 
763 #endif // BALL_MATHS_ANGLE_H