BALL  1.4.1
angle.h
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 
00005 #ifndef BALL_MATHS_ANGLE_H
00006 #define BALL_MATHS_ANGLE_H
00007 
00008 #ifndef BALL_COMMON_EXCEPTION_H
00009 # include <BALL/COMMON/exception.h>
00010 #endif
00011 
00012 #ifndef BALL_COMMON_DEBUG_H
00013 # include <BALL/COMMON/debug.h>
00014 #endif
00015 
00016 #ifndef BALL_COMMON_CREATE_H
00017 # include <BALL/COMMON/create.h>
00018 #endif
00019 
00020 #ifndef BALL_MATHS_COMMON_H
00021 # include <BALL/MATHS/common.h>
00022 #endif
00023 
00024 namespace BALL 
00025 {
00031   template <typename T>
00032   class TAngle;
00033 
00034   template <typename T>
00035   BALL_INLINE
00036   TAngle<T> operator * (const T& val, const TAngle<T>& angle);
00037 
00038   template <typename T>
00039   BALL_INLINE
00040   TAngle<T> operator + (const T& val, const TAngle<T>& angle);
00041 
00042   template <typename T>
00043   BALL_INLINE
00044   TAngle<T> operator - (const T& val, const TAngle<T>& angle);
00045 
00051   template <typename T>
00052   class TAngle
00053   {
00054     public:
00055 
00056     BALL_CREATE(TAngle<T>)
00057 
00058     
00061 
00067     enum Range
00068     {
00069       // no limitations
00070       RANGE__UNLIMITED = 0, 
00071       // 0 <= angle <= 360, 0 <= angle <= (Constants::PI * 2)
00072       RANGE__UNSIGNED  = 1, 
00073       // -180 <= angle <= 180, -Constants::PI <= angle <= Constants::PI
00074       RANGE__SIGNED    = 2 
00075     };
00077 
00080 
00084     TAngle();
00085 
00091     TAngle(const TAngle& angle);
00092 
00100     explicit TAngle(const T& new_value, bool radian = true);
00101 
00104     virtual ~TAngle()
00105     {
00106     }
00107 
00111     virtual void clear()
00112     {
00113       value = (T)0;
00114     }
00116 
00120 
00123     void swap(TAngle& angle);
00124 
00131     void set(const T& new_value, bool radian = true);
00132 
00136     void set(const TAngle& angle);
00137 
00140     TAngle& operator = (const TAngle& angle);
00141 
00147     TAngle& operator = (const T& new_value);
00148 
00152     void get(TAngle& angle) const;
00153 
00158     void get(T& val, bool radian = true) const;
00159 
00161 
00164 
00168     operator T () const;
00169 
00173     T toRadian() const
00174   ;
00175 
00180     static T toRadian(const T& degree);
00181 
00185     T toDegree() const;
00186 
00191     static T toDegree(const T& radian);
00192 
00199     void normalize(Range range);
00200 
00203     void negate();
00204 
00207     TAngle operator + () const;
00208 
00211     TAngle operator - () const;
00212 
00217     TAngle& operator += (const TAngle& angle);
00218 
00223     TAngle& operator += (const T& val);
00224 
00229     TAngle operator + (const TAngle& angle);
00230 
00235     TAngle& operator -= (const TAngle& angle);
00236 
00241     TAngle& operator -= (const T& val);
00242 
00247     TAngle operator - (const TAngle& angle);
00248 
00253     TAngle& operator *= (const TAngle& angle);
00254 
00259     TAngle& operator *= (const T& val);
00260 
00266     TAngle& operator /= (const TAngle& angle);
00267 
00273     TAngle& operator /= (const T& val);
00274 
00280     TAngle operator / (const TAngle& val);
00281 
00283 
00286 
00293     bool operator == (const TAngle& angle) const;
00294 
00301     bool operator != (const TAngle& angle) const;
00302 
00309     bool operator < (const TAngle& angle) const;
00310 
00317     bool operator < (const T& val) const;
00318 
00325     bool operator <= (const TAngle& angle) const;
00326 
00333     bool operator >= (const TAngle& angle) const;
00334 
00341     bool operator > (const TAngle& angle) const;
00342 
00349     bool isEquivalent(TAngle angle) const;
00350 
00352 
00355 
00360     bool isValid () const;
00361 
00368     void dump(std::ostream& s = std::cout, Size depth = 0) const;
00369 
00371 
00374 
00377     T value;
00378 
00380   };
00382 
00383   template <typename T>
00384   TAngle<T>::TAngle()
00385     : value((T)0)
00386   {
00387   }
00388 
00389   template <typename T>
00390   TAngle<T>::TAngle(const TAngle& angle)
00391     : value((T)angle.value)
00392   {
00393   }
00394 
00395   template <typename T>
00396   TAngle<T>::TAngle(const T& new_value, bool radian)
00397     : value((radian == true)
00398        ? (T)new_value 
00399        : (T)BALL_ANGLE_DEGREE_TO_RADIAN((double)new_value))
00400   {
00401   }
00402 
00403   template <typename T>
00404   void TAngle<T>::swap(TAngle& angle)
00405   {
00406     T temp = value;
00407     value = angle.value;
00408     angle.value = temp;
00409   }
00410 
00411   template <typename T>
00412   void TAngle<T>::set(const TAngle& angle)
00413   {
00414     value = angle.value;
00415   }
00416 
00417   template <typename T>
00418   void TAngle<T>::set(const T& new_value, bool radian)
00419   {
00420     value = (radian == true)
00421        ? new_value 
00422        : BALL_ANGLE_DEGREE_TO_RADIAN(new_value);
00423   }
00424 
00425   template <typename T>
00426   TAngle<T>& TAngle<T>::operator = (const TAngle& angle)
00427   {
00428     value = angle.value;
00429     return *this;
00430   }
00431 
00432   template <typename T>
00433   TAngle<T>& TAngle<T>::operator = (const T& new_value)
00434   {
00435     value = new_value;
00436     return *this;
00437   }
00438 
00439   template <typename T>
00440   void TAngle<T>::get(TAngle& angle) const
00441   {
00442     angle.value = value;
00443   }
00444 
00445   template <typename T>
00446   void TAngle<T>::get(T& val, bool radian) const
00447   {
00448     val = (radian == true)
00449            ? value 
00450            : BALL_ANGLE_RADIAN_TO_DEGREE(value);
00451   }
00452 
00453   template <typename T>
00454   TAngle<T>::operator T () const
00455   {
00456     return value;
00457   }
00458 
00459   template <typename T>
00460   T TAngle<T>::toRadian() const
00461   {
00462     return value;
00463   }
00464 
00465   template <typename T>
00466   T TAngle<T>::toRadian(const T& degree)
00467   {
00468     return BALL_ANGLE_DEGREE_TO_RADIAN(degree);
00469   }
00470 
00471   template <typename T>
00472   T TAngle<T>::toDegree() const
00473   {
00474     if (value == (T) 0.0) return (T) 0.0;
00475     return BALL_ANGLE_RADIAN_TO_DEGREE(value);
00476   }
00477 
00478   template <typename T>
00479   T TAngle<T>::toDegree(const T& radian)
00480   {
00481     if (radian == (T) 0.0) return (T) 0.0;
00482     return BALL_ANGLE_RADIAN_TO_DEGREE(radian);
00483   }
00484 
00485   template <typename T>
00486   void TAngle<T>::normalize(Range range)
00487   {
00488     if (range == RANGE__UNLIMITED)
00489     {
00490       return;
00491     }
00492 
00493     long mod_factor = (long)(value / (2 * Constants::PI));
00494     value -= mod_factor * (Constants::PI * 2);
00495 
00496     while (Maths::isGreater(value, (Constants::PI * 2)))
00497     {
00498       value -= (Constants::PI * 2);
00499     }
00500     while (Maths::isLess(value, -(Constants::PI * 2)))
00501     {
00502       value += (Constants::PI * 2);
00503     }
00504     if (range == RANGE__SIGNED) // invariant: -180 to 180:
00505     {
00506       if (Maths::isGreater(value, Constants::PI)) 
00507       {
00508         value -= (Constants::PI * 2);
00509       }
00510     } 
00511     else 
00512     { // invariant: 0 to 360:
00513       if (Maths::isLess(value, 0)) 
00514       {
00515         value += (Constants::PI * 2);
00516       }
00517     }
00518   }
00519 
00520   template <typename T>
00521   void TAngle<T>::negate() 
00522   {
00523     value = -value;
00524   }
00525 
00526   template <typename T>
00527   TAngle<T> TAngle<T>::operator + () const 
00528   {
00529     return *this;
00530   }
00531 
00532   template <typename T>
00533   TAngle<T> TAngle<T>::operator - () const 
00534   {
00535     return TAngle(-value);
00536   }
00537 
00538   template <typename T>
00539   TAngle<T>& TAngle<T>::operator += (const TAngle& angle) 
00540   {
00541     value += angle.value;
00542     return *this;
00543   }
00544 
00545   template <typename T>
00546   TAngle<T>& TAngle<T>::operator += (const T& val) 
00547   {
00548     value += val;
00549     return *this;
00550   }
00551 
00552   template <typename T>
00553   TAngle<T> TAngle<T>::operator + (const TAngle& angle)
00554   {
00555     return TAngle(value + angle.value);
00556   }
00557 
00558   template <typename T>
00559   TAngle<T>& TAngle<T>::operator -= (const TAngle& angle)
00560   {
00561     value -= angle.value;
00562     return *this;
00563   }
00564 
00565   template <typename T>
00566   TAngle<T>& TAngle<T>::operator -= (const T& val)
00567   {
00568     value -= val;
00569     return *this;
00570   }
00571 
00572   template <typename T>
00573   TAngle<T> TAngle<T>::operator - (const TAngle& angle) 
00574   {
00575     return TAngle(value - angle.value);
00576   }
00577 
00578   template <typename T>
00579   TAngle<T>& TAngle<T>::operator *= (const TAngle& angle)
00580   {
00581     value *= angle.value;
00582     return *this;
00583   }
00584 
00585   template <typename T>
00586   TAngle<T>& TAngle<T>::operator *= (const T& val)
00587   {
00588     value *= val;
00589     return *this;
00590   }
00591 
00592   template <typename T>
00593   TAngle<T>& TAngle<T>::operator /= (const TAngle& angle)
00594   {
00595     if (angle.value == 0)
00596     {
00597       throw Exception::DivisionByZero(__FILE__, __LINE__);
00598     }
00599     value /= angle.value;
00600     return *this;
00601   }
00602 
00603 
00604   template <typename T>
00605   TAngle<T>& TAngle<T>::operator /= (const T& val) 
00606   {
00607     if (val == 0)
00608     {
00609       throw Exception::DivisionByZero(__FILE__, __LINE__);
00610     }
00611 
00612     value /= val;
00613     return *this;
00614   }
00615 
00616 
00617   template <typename T>
00618   TAngle<T> TAngle<T>::operator / (const TAngle<T>& val) 
00619   {
00620     if (val.value == 0)
00621     {
00622       throw Exception::DivisionByZero(__FILE__, __LINE__);
00623     }
00624 
00625     return TAngle(value / val.value);
00626   }
00627 
00628   template <typename T>
00629   bool TAngle<T>::operator == (const TAngle& angle) const
00630   {
00631     return Maths::isEqual(value, angle.value);
00632   }
00633 
00634   template <typename T>
00635   bool TAngle<T>::operator != (const TAngle& angle) const 
00636   {
00637     return Maths::isNotEqual(value, angle.value);
00638   }
00639 
00640   template <typename T>
00641   bool TAngle<T>::operator < (const TAngle& angle) const
00642   {
00643     return Maths::isLess(value, angle.value);
00644   }
00645 
00646   template <typename T>
00647   bool TAngle<T>::operator < (const T& val) const
00648   {
00649     return Maths::isLess(value, val);
00650   }
00651 
00652   template <typename T>
00653   bool TAngle<T>::operator <= (const TAngle& angle) const
00654   {
00655     return Maths::isLessOrEqual(value, angle.value);
00656   }
00657 
00658   template <typename T>
00659   bool TAngle<T>::operator >= (const TAngle& angle) const 
00660   {
00661     return Maths::isGreaterOrEqual(value, angle.value);
00662   }
00663 
00664   template <typename T>
00665   bool TAngle<T>::operator > (const TAngle& angle) const 
00666     
00667   {
00668     return Maths::isGreater(value, angle.value);
00669   }
00670 
00671   template <typename T>
00672   bool TAngle<T>::isEquivalent(TAngle angle) const
00673   {
00674     TAngle this_angle(*this);
00675 
00676     this_angle.normalize(RANGE__UNSIGNED);
00677     angle.normalize(RANGE__UNSIGNED);
00678 
00679     return (this_angle == angle);
00680   }
00681 
00682   template <typename T>
00683   bool TAngle<T>::isValid() const 
00684   {
00685     return true;
00686   }
00687 
00688   template <typename T>
00689   void TAngle<T>::dump(std::ostream& s, Size depth) const
00690   {
00691     BALL_DUMP_STREAM_PREFIX(s);
00692 
00693     BALL_DUMP_HEADER(s, this, this);
00694 
00695     BALL_DUMP_DEPTH(s, depth);
00696     s << "  value: " << value << std::endl;
00697 
00698     BALL_DUMP_STREAM_SUFFIX(s);
00699   }
00700 
00705   typedef TAngle<float> Angle;
00706 
00710   template <typename T>
00711   BALL_INLINE
00712   TAngle<T> operator * (const T& val, const TAngle<T>& angle)
00713   {
00714     return TAngle<T>(val * angle.value);
00715   }
00716 
00720   template <typename T>
00721   BALL_INLINE
00722   TAngle<T> operator + (const T& val, const TAngle<T>& angle) 
00723   {
00724     return TAngle<T>(val + angle.value);
00725   }
00726 
00730   template <typename T>
00731   BALL_INLINE
00732   TAngle<T> operator - (const T& val, const TAngle<T>& angle) 
00733   {
00734     return TAngle<T>(val - angle.value);
00735   }
00736 
00740   template <typename T>
00741   std::istream& operator >> (std::istream& s, TAngle<T>& angle)
00742   {
00743     char c;
00744     s >> c >> angle.value >> c;
00745     return s;
00746   }
00747 
00753   template <typename T>
00754   std::ostream& operator << (std::ostream& s, const TAngle<T>& angle)
00755   {
00756     s << '(' << angle.value << ')';
00757 
00758     return s;
00759   }
00760 
00761 } // namespace BALL
00762 
00763 #endif // BALL_MATHS_ANGLE_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines