Go to the documentation of this file.00001
00008
00009
00010
00011
00012 #ifndef ECL_GEOMETRY_ANGLE_HPP_
00013 #define ECL_GEOMETRY_ANGLE_HPP_
00014
00015
00016
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
00029
00030
00031 namespace ecl {
00032
00040 template <typename T>
00041 ECL_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_PUBLIC T degrees_to_radians(const T °rees, 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
00106
00112 template <class T, typename Enable = void>
00113 class ECL_LOCAL Angle {
00114 private:
00121 Angle() {};
00122 };
00123
00135 template <typename T>
00136 class ECL_PUBLIC Angle<T, typename enable_if<is_float<T> >::type> {
00137 public:
00138
00139
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
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
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
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
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
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 }
00423
00424 #endif