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
00026
00027
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 °rees, 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
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
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
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
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
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
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
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 }
00422
00423 #endif