00001 /* 00002 * Angle.hpp 00003 * 00004 * Created on: Oct 27, 2011 00005 * Author: mriedel 00006 */ 00007 00008 #ifndef ANGLE_HPP_ 00009 #define ANGLE_HPP_ 00010 00011 #include <telekyb_defines/telekyb_defines.hpp> 00012 00013 #include <math.h> 00014 #include <string> 00015 00016 namespace TELEKYB_NAMESPACE 00017 { 00018 00019 class Angle{ 00020 private: 00021 double theta; 00022 static const double M_2PI; /*for efficency*/ 00023 00024 public: 00025 // These are Static functions that can be used directly 00027 static inline double norm2Pi(double a) { 00028 if (a >= M_2PI || a < 0.0) { 00029 a = fmod(a, M_2PI); //in [-2*M_PI,2*M_PI] 00030 if (a < 0.0) 00031 a += M_2PI; //in [0,2*M_PI] 00032 if (a >= M_2PI) 00033 a -= M_2PI; 00034 } 00035 return a; 00036 } 00038 static inline double normPi(double a, int opt = 0) { 00039 if (a > M_PI || a <= -M_PI) { 00040 a = fmod(a, M_2PI); //in [-2*M_PI,2*M_PI] 00041 00042 if (opt == 0) { 00043 if (a <= -M_PI) 00044 a += M_2PI; 00045 } 00046 if (opt == 1) { 00047 if (a < -M_PI) 00048 a += M_2PI; 00049 } 00050 if (a > M_PI) 00051 a -= M_2PI; 00052 } 00053 return a; 00054 } 00056 static inline double normMinus2Pi(double a) { 00057 if (a >= 0.0 || a < -M_2PI) { 00058 a = fmod(a, M_2PI); //in [-2*M_PI,2*M_PI] 00059 if (a < -M_2PI) 00060 a += M_2PI; //in [0,2*M_PI] 00061 if (a >= 0.0) 00062 a -= M_2PI; 00063 } 00064 return a; 00065 } 00066 00067 00069 Angle() { 00070 theta = 0.0; 00071 }; 00073 Angle(const double& t) { 00074 theta = norm2Pi(t); 00075 }; 00077 Angle(const Angle& rhs) { 00078 theta = norm2Pi(rhs.dCast()); 00079 }; 00081 Angle& operator=(const Angle& rhs){ 00082 if (this != &rhs){ // Not necessary in this case but it is useful to don't forget it 00083 theta = norm2Pi(rhs.dCast()); 00084 } 00085 return *this; 00086 } 00088 Angle& operator+=(const Angle& a) { 00089 theta = norm2Pi(theta + a.theta); 00090 return *this; 00091 } 00093 Angle& operator-=(const Angle& other) { 00094 double myTheta = theta >= other.theta ? theta : theta + 2.0*M_PI; 00095 theta = norm2Pi(myTheta - other.theta); 00096 return *this; 00097 } 00099 Angle& operator*=(const Angle& a) { 00100 theta = norm2Pi(theta * a.theta); 00101 return *this; 00102 } 00104 Angle& operator*=(const double& d) { 00105 theta = norm2Pi(theta * d); 00106 return *this; 00107 } 00109 Angle operator+(const Angle &other) const { 00110 return Angle(*this) += other; 00111 } 00113 Angle operator-(const Angle &other) const { 00114 return Angle(*this) -= other; 00115 } 00117 Angle operator*(const Angle &other) const { 00118 return Angle(*this) *= other; 00119 } 00121 Angle operator*(const double& d) const { 00122 return (Angle(*this) *= d); 00123 } 00125 bool operator==(const Angle &other) const { 00126 if( (other.dCast()) == theta) return true; 00127 else return false; 00128 } 00130 bool operator!=(const Angle &other) const { 00131 return !(*this == other); 00132 } 00134 double dCast() const { 00135 return theta; 00136 } 00137 00139 double dCast2Pi() const { 00140 return norm2Pi(theta); 00141 } 00142 00144 double dCastPi(int opt=0) const { 00145 if(opt==0) return normPi(theta); 00146 if(opt==1) return normPi(theta,1); 00147 00148 // never happens 00149 return normPi(theta); 00150 } 00152 double dCastDeg() const { 00153 return (theta*180.0)/M_PI; 00154 } 00155 00157 // UCoordmm dCastHDeg() const { 00158 // return (UCoordmm)((theta*18000.0)/M_PI); 00159 // } 00164 double alDiff(const Angle &other) const; 00165 00170 double ccwDiff(const Angle &other) const; 00171 00176 double cwDiff(const Angle &other) const; 00177 00182 // bool almostEqual(const Angle& A, const double& toll) const; 00183 00189 Angle nearestMean(const Angle &other, double w1 = 0.5) const; 00190 00195 Angle ccwMean(const Angle &other) const; 00196 00201 Angle cwMean(const Angle &other) const; 00202 00206 std::string toString(int precision=2) const; 00207 }; 00208 00209 } 00210 00211 #endif /* ANGLE_HPP_ */