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 #include "macros.hpp"
00026 
00027 /*****************************************************************************
00028 ** Namespaces
00029 *****************************************************************************/
00030 
00031 namespace ecl {
00032 
00040 template <typename T>
00041 ecl_geometry_PUBLIC T radians_to_degrees(const T &radians, typename enable_if<ecl::is_float<T> >::type* dummy = 0) {
00042         static const T rads_to_degs = 180.0/pi;
00043         return radians*rads_to_degs;
00044 }
00045 
00053 template <typename T>
00054 ecl_geometry_PUBLIC T degrees_to_radians(const T &degrees, typename enable_if<ecl::is_float<T> >::type* dummy = 0) {
00055         static const T degs_to_rads = pi/180.0;
00056         return degrees*degs_to_rads;
00057 }
00058 
00068 ecl_geometry_PUBLIC const float& wrap_angle(float &angle);
00069 
00080 ecl_geometry_PUBLIC float wrap_angle(const float &angle);
00090 ecl_geometry_PUBLIC const double& wrap_angle(double &angle);
00091 
00102 ecl_geometry_PUBLIC double wrap_angle(const double &angle);
00103 
00104 /*****************************************************************************
00105 ** Interface [Angle]
00106 *****************************************************************************/
00112 template <class T, typename Enable = void>
00113 class ecl_geometry_PUBLIC Angle {
00114 private:
00121         Angle() {};
00122 };
00123 
00135 template <typename T>
00136 class ecl_geometry_PUBLIC Angle<T, typename enable_if<is_float<T> >::type> {
00137 public:
00138         /*********************
00139         ** Typedefs
00140         **********************/
00141         typedef ecl::linear_algebra::Matrix<T,2,2> RotationMatrix;
00150         Angle(const T &angle = 0.0) : value(angle) { wrap_angle(value); }
00155         Angle(const RotationMatrix &rotation) {
00156                 value = std::atan2(rotation(1,0),rotation(0,0));
00157         }
00158 
00168         const Angle<T>& operator=(const T &angle);
00169         /*********************
00170         ** Math Operators
00171         **********************/
00180         Angle<T> operator+(const T &angle) const;
00189         Angle<T> operator+(const Angle<T> &angle) const;
00197         void operator+=(const T &angle);
00205         void operator+=(const Angle<T> &angle);
00214         Angle<T> operator-(const T &angle) const;
00223         Angle<T> operator-(const Angle<T> &angle) const;
00231         void operator-=(const T &angle);
00239         void operator-=(const Angle<T> &angle);
00248         Angle<T> operator*(const T &scalar) const;
00256         void operator*=(const T &scalar);
00257 
00258         /*********************
00259         ** Casting
00260         **********************/
00270         operator const T&() const { return value; }
00281         T degrees();
00282 
00287         RotationMatrix rotationMatrix() const {
00288                 T c = std::cos(value);
00289                 T s = std::sin(value);
00290                 return (RotationMatrix() << c, -s, s, c).finished();
00291         }
00292 
00306         static Angle<T> Degrees(const T &angle);
00320         static Angle<T> Radians(const T &angle);
00321 
00322 private:
00323         T value;
00324 };
00325 
00330 /*****************************************************************************
00331 ** Implementation
00332 *****************************************************************************/
00333 
00334 template <typename T>
00335 T Angle<T, typename enable_if<is_float<T> >::type>::degrees() {
00336         return radians_to_degrees(value);
00337 }
00338 
00339 template <typename T>
00340 const Angle<T>& Angle<T, typename enable_if<is_float<T> >::type>::operator=(const T &angle) {
00341         value = angle;
00342         wrap_angle(value);
00343         return *this;
00344 }
00345 
00346 /*****************************************************************************
00347 ** Operators
00348 *****************************************************************************/
00349 
00350 template <typename T>
00351 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator+(const T &angle) const {
00352         return Angle<T>(wrap_angle(value+angle));
00353 }
00354 
00355 template <typename T>
00356 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator+(const Angle<T> &angle) const {
00357         return Angle<T>(wrap_angle(value+angle.value));
00358 }
00359 
00360 template <typename T>
00361 void Angle<T, typename enable_if<is_float<T> >::type>::operator+=(const T &angle) {
00362         value += angle;
00363         wrap_angle(value);
00364 }
00365 
00366 template <typename T>
00367 void Angle<T, typename enable_if<is_float<T> >::type>::operator+=(const Angle<T> &angle) {
00368         value += angle.value;
00369         wrap_angle(value);
00370 }
00371 
00372 template <typename T>
00373 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator-(const T &angle) const {
00374         return Angle<T>(wrap_angle(value-angle));
00375 }
00376 
00377 template <typename T>
00378 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator-(const Angle<T> &angle) const {
00379         return Angle<T>(wrap_angle(value-angle.value));
00380 }
00381 
00382 template <typename T>
00383 void Angle<T, typename enable_if<is_float<T> >::type>::operator-=(const T &angle) {
00384         value -= angle;
00385         wrap_angle(value);
00386 }
00387 
00388 template <typename T>
00389 void Angle<T, typename enable_if<is_float<T> >::type>::operator-=(const Angle<T> &angle) {
00390         value -= angle.value;
00391         wrap_angle(value);
00392 }
00393 
00394 template <typename T>
00395 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::operator*(const T &scalar) const {
00396         return Angle<T>(wrap_angle(scalar*value));
00397 }
00398 
00399 template <typename T>
00400 void Angle<T, typename enable_if<is_float<T> >::type>::operator*=(const T &scalar) {
00401         value *= scalar;
00402         wrap_angle(value);
00403 }
00404 
00405 /*****************************************************************************
00406 ** Statics
00407 *****************************************************************************/
00408 
00409 template <typename T>
00410 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::Degrees(const T &angle) {
00411         return Angle<T>(degrees_to_radians(angle));
00412 }
00413 
00414 template <typename T>
00415 Angle<T> Angle<T, typename enable_if<is_float<T> >::type>::Radians(const T &angle) {
00416         return Angle<T>(angle);
00417 }
00422 } // namespace ecl
00423 
00424 #endif /* ECL_GEOMETRY_ANGLE_HPP_ */


ecl_geometry
Author(s): Daniel Stonier
autogenerated on Mon Jul 3 2017 02:21:51