angle.hpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Ifdefs
00010 *****************************************************************************/
00011 
00012 #ifndef ECL_GEOMETRY_ANGLE_HPP_
00013 #define ECL_GEOMETRY_ANGLE_HPP_
00014 
00015 /*****************************************************************************
00016 ** Includes
00017 *****************************************************************************/
00018 
00019 #include <cmath>
00020 #include <ecl/config/macros.hpp>
00021 #include <ecl/linear_algebra.hpp>
00022 #include <ecl/type_traits/fundamental_types.hpp>
00023 #include <ecl/mpl/enable_if.hpp>
00024 #include <ecl/math/constants.hpp>
00025 
00026 /*****************************************************************************
00027 ** Namespaces
00028 *****************************************************************************/
00029 
00030 namespace ecl {
00031 
00039 template <typename T>
00040 ECL_PUBLIC T radians_to_degrees(const T &radians, typename enable_if<ecl::is_float<T> >::type* dummy = 0) {
00041         static const T rads_to_degs = 180.0/pi;
00042         return radians*rads_to_degs;
00043 }
00044 
00052 template <typename T>
00053 ECL_PUBLIC T degrees_to_radians(const T &degrees, typename enable_if<ecl::is_float<T> >::type* dummy = 0) {
00054         static const T degs_to_rads = pi/180.0;
00055         return degrees*degs_to_rads;
00056 }
00057 
00067 ECL_PUBLIC const float& wrap_angle(float &angle);
00068 
00079 ECL_PUBLIC float wrap_angle(const float &angle);
00089 ECL_PUBLIC const double& wrap_angle(double &angle);
00090 
00101 ECL_PUBLIC double wrap_angle(const double &angle);
00102 
00103 /*****************************************************************************
00104 ** Interface [Angle]
00105 *****************************************************************************/
00111 template <class T, typename Enable = void>
00112 class ECL_LOCAL Angle {
00113 private:
00120         Angle() {};
00121 };
00122 
00134 template <typename T>
00135 class ECL_PUBLIC Angle<T, typename enable_if<is_float<T> >::type> {
00136 public:
00137         /*********************
00138         ** Typedefs
00139         **********************/
00140         typedef ecl::linear_algebra::Matrix<T,2,2> RotationMatrix;
00149         Angle(const T &angle = 0.0) : value(angle) { wrap_angle(value); }
00154         Angle(const RotationMatrix &rotation) {
00155                 value = std::atan2(rotation(1,0),rotation(0,0));
00156         }
00157 
00167         const Angle<T>& operator=(const T &angle);
00168         /*********************
00169         ** Math Operators
00170         **********************/
00179         Angle<T> operator+(const T &angle) const;
00188         Angle<T> operator+(const Angle<T> &angle) const;
00196         void operator+=(const T &angle);
00204         void operator+=(const Angle<T> &angle);
00213         Angle<T> operator-(const T &angle) const;
00222         Angle<T> operator-(const Angle<T> &angle) const;
00230         void operator-=(const T &angle);
00238         void operator-=(const Angle<T> &angle);
00247         Angle<T> operator*(const T &scalar) const;
00255         void operator*=(const T &scalar);
00256 
00257         /*********************
00258         ** Casting
00259         **********************/
00269         operator const T&() const { return value; }
00280         T degrees();
00281 
00286         RotationMatrix rotationMatrix() const {
00287                 T c = std::cos(value);
00288                 T s = std::sin(value);
00289                 return (RotationMatrix() << c, -s, s, c).finished();
00290         }
00291 
00305         static Angle<T> Degrees(const T &angle);
00319         static Angle<T> Radians(const T &angle);
00320 
00321 private:
00322         T value;
00323 };
00324 
00329 /*****************************************************************************
00330 ** Implementation
00331 *****************************************************************************/
00332 
00333 template <typename T>
00334 T Angle<T, typename enable_if<is_float<T> >::type>::degrees() {
00335         return radians_to_degrees(value);
00336 }
00337 
00338 template <typename T>
00339 const Angle<T>& Angle<T, typename enable_if<is_float<T> >::type>::operator=(const T &angle) {
00340         value = angle;
00341         wrap_angle(value);
00342         return *this;
00343 }
00344 
00345 /*****************************************************************************
00346 ** Operators
00347 *****************************************************************************/
00348 
00349 template <typename T>
00350 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator+(const T &angle) const {
00351         return Angle<T>(wrap_angle(value+angle));
00352 }
00353 
00354 template <typename T>
00355 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator+(const Angle<T> &angle) const {
00356         return Angle<T>(wrap_angle(value+angle.value));
00357 }
00358 
00359 template <typename T>
00360 void Angle<T, typename enable_if<is_float<T> >::type>::operator+=(const T &angle) {
00361         value += angle;
00362         wrap_angle(value);
00363 }
00364 
00365 template <typename T>
00366 void Angle<T, typename enable_if<is_float<T> >::type>::operator+=(const Angle<T> &angle) {
00367         value += angle.value;
00368         wrap_angle(value);
00369 }
00370 
00371 template <typename T>
00372 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator-(const T &angle) const {
00373         return Angle<T>(wrap_angle(value-angle));
00374 }
00375 
00376 template <typename T>
00377 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator-(const Angle<T> &angle) const {
00378         return Angle<T>(wrap_angle(value-angle.value));
00379 }
00380 
00381 template <typename T>
00382 void Angle<T, typename enable_if<is_float<T> >::type>::operator-=(const T &angle) {
00383         value -= angle;
00384         wrap_angle(value);
00385 }
00386 
00387 template <typename T>
00388 void Angle<T, typename enable_if<is_float<T> >::type>::operator-=(const Angle<T> &angle) {
00389         value -= angle.value;
00390         wrap_angle(value);
00391 }
00392 
00393 template <typename T>
00394 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator*(const T &scalar) const {
00395         return Angle<T>(wrap_angle(scalar*value));
00396 }
00397 
00398 template <typename T>
00399 void Angle<T, typename enable_if<is_float<T> >::type>::operator*=(const T &scalar) {
00400         value *= scalar;
00401         wrap_angle(value);
00402 }
00403 
00404 /*****************************************************************************
00405 ** Statics
00406 *****************************************************************************/
00407 
00408 template <typename T>
00409 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::Degrees(const T &angle) {
00410         return Angle<T>(degrees_to_radians(angle));
00411 }
00412 
00413 template <typename T>
00414 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::Radians(const T &angle) {
00415         return Angle<T>(angle);
00416 }
00421 } // namespace ecl
00422 
00423 #endif /* ECL_GEOMETRY_ANGLE_HPP_ */


ecl_geometry
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:13:11