00001 /*!@file Util/Angle.H A simple class to embody an angular value */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/Angle.H $ 00035 // $Id: Angle.H 10221 2008-09-07 17:45:52Z lior $ 00036 // 00037 00038 #ifndef ANGLE_H_DEFINED 00039 #define ANGLE_H_DEFINED 00040 00041 #include <cmath> 00042 #include <deque> 00043 00044 //! Embodiment of an angular value 00045 /*! This class provides functions to manipulate and do maths on 00046 angles. The internal representation is a double value in degrees in 00047 the range ]-180.0 .. 180.0]. This is an all-inlined class, so there 00048 is no Angle.C file. */ 00049 class Angle 00050 { 00051 public: 00052 // ###################################################################### 00053 /*! @name Constructors, destructor, assigments, and conversions */ 00054 //@{ 00055 00056 //! Constructor. Initial value should be in degrees. 00057 inline Angle(const double val = 0.0); 00058 00059 //! Copy constructor 00060 inline Angle(const Angle& ang); 00061 00062 //! Destructor 00063 inline ~Angle(); 00064 00065 //! Assignment 00066 inline Angle& operator=(const Angle& ang); 00067 00068 //! Assignment 00069 inline Angle& operator=(const double ang); 00070 00071 //! Set a new value in degrees 00072 inline void setVal(const double val); 00073 00074 //! Get current value in degrees in ]-180.0 .. 180.0] 00075 inline double getVal() const; 00076 00077 //! Conversion from radians 00078 inline void setRadians(const double val); 00079 00080 //! Get value in radians (in [-pi .. pi]) 00081 inline double getRadians() const; 00082 00083 //@} 00084 00085 // ###################################################################### 00086 /*! @name Arithmetic operators */ 00087 //@{ 00088 00089 //! Addition. Result is taken modulo 360 and remains in ]-180.0 .. 180.0] 00090 inline Angle& operator+=(const Angle& other); 00091 00092 //! Subtraction. Result is taken modulo 360 and remains in ]-180.0 .. 180.0] 00093 inline Angle& operator-=(const Angle& other); 00094 00095 //! Multiplication by a constant. Result remains in ]-180.0 .. 180.0] 00096 inline Angle& operator*=(const double fac); 00097 00098 //! Division by a constant. Result remains in ]-180.0 .. 180.0] 00099 inline Angle& operator/=(const double fac); 00100 00101 //! Addition of two angles. Result remains in ]-180.0 .. 180.0] 00102 inline Angle operator+(const Angle& other) const; 00103 00104 //! Subtraction of two angles. Result remains in ]-180.0 .. 180.0] 00105 inline Angle operator-(const Angle& other) const; 00106 00107 //! Combine with another angle, in vector style 00108 /*! This computes the sum of a unit vector with our angle and a 00109 vector with other's angle and optionally a given length. The 00110 result is the angle of the combined vector. Special cases (e.g., 00111 other is the exact opposite of us) are handled like atan2() 00112 would. */ 00113 inline void vectorAdd(const Angle& other, const double otherlen = 1.0); 00114 00115 //! Comparison. USE WITH CAUTION! 00116 inline bool operator<(const Angle& other) const; 00117 00118 //! Comparison. USE WITH CAUTION! 00119 inline bool operator>(const Angle& other) const; 00120 00121 //! Comparison. USE WITH CAUTION! 00122 inline bool operator!=(const Angle& other) const; 00123 00124 //! Comparison. USE WITH CAUTION! 00125 inline bool operator<(const double other) const; 00126 00127 //! Comparison. USE WITH CAUTION! 00128 inline bool operator>(const double other) const; 00129 00130 //! Comparison. USE WITH CAUTION! 00131 inline bool operator!=(const double other) const; 00132 00133 //@} 00134 00135 private: 00136 inline void fixValue(); // apply modulo to enforce ]-180.0 .. 180.0] 00137 00138 double angle; 00139 }; 00140 00141 // ###################################################################### 00142 // ##### Free functions that manipulate angles: 00143 // ###################################################################### 00144 00145 //! Compute the vector average of a bunch of angles 00146 /*! Each angle is assumed to be associated with a vector of unit 00147 length, and the angle of the vector sum of all unit vectors is 00148 resturned. */ 00149 inline Angle averageVectorAngle(std::deque<Angle>::const_iterator astart, 00150 std::deque<Angle>::const_iterator aend); 00151 00152 //! Compute the weighted vector average of a bunch of angles 00153 /*! The length of each vector starts with 1.0 and then is multiplied 00154 by factor each at each iteration, thus providing an exponential 00155 length decay. Each angle is assumed to be associated with a vector 00156 of given length length, and the angle of the vector sum of all 00157 vectors is resturned. */ 00158 inline Angle averageVectorAngle(std::deque<Angle>::const_iterator astart, 00159 std::deque<Angle>::const_iterator aend, 00160 const double factor); 00161 00162 00163 00164 // ###################################################################### 00165 // ########## Inlined methods: 00166 // ###################################################################### 00167 inline Angle::Angle(const double val) : 00168 angle(val) 00169 { fixValue(); } 00170 00171 // ###################################################################### 00172 inline Angle::Angle(const Angle& ang) : 00173 angle(ang.angle) 00174 { } 00175 00176 // ###################################################################### 00177 inline Angle::~Angle() 00178 { } 00179 00180 // ###################################################################### 00181 inline Angle& Angle::operator=(const Angle& ang) 00182 { angle = ang.angle; return *this; } 00183 00184 // ###################################################################### 00185 inline Angle& Angle::operator=(const double ang) 00186 { angle = ang; return *this; } 00187 00188 // ###################################################################### 00189 inline void Angle::setVal(const double val) 00190 { angle = val; fixValue(); } 00191 00192 // ###################################################################### 00193 inline double Angle::getVal() const 00194 { return angle; } 00195 00196 // ###################################################################### 00197 inline void Angle::setRadians(const double val) 00198 { angle = val * 180.0 / M_PI; fixValue(); } 00199 00200 // ###################################################################### 00201 inline double Angle::getRadians() const 00202 { return angle * M_PI / 180.0; } 00203 00204 // ###################################################################### 00205 inline Angle& Angle::operator+=(const Angle& other) 00206 { angle += other.angle; fixValue(); return *this; } 00207 00208 // ###################################################################### 00209 inline Angle& Angle::operator-=(const Angle& other) 00210 { angle -= other.angle; fixValue(); return *this; } 00211 00212 // ###################################################################### 00213 inline Angle& Angle::operator*=(const double fac) 00214 { angle *= fac; fixValue(); return *this; } 00215 00216 // ###################################################################### 00217 inline Angle& Angle::operator/=(const double fac) 00218 { angle /= fac; fixValue(); return *this; } 00219 00220 // ###################################################################### 00221 inline Angle Angle::operator+(const Angle& other) const 00222 { Angle a(*this); a += other; a.fixValue(); return a; } 00223 00224 // ###################################################################### 00225 inline Angle Angle::operator-(const Angle& other) const 00226 { Angle a(*this); a -= other; a.fixValue(); return a; } 00227 00228 // ###################################################################### 00229 inline void Angle::vectorAdd(const Angle& other, const double otherlen) 00230 { 00231 // compute the vector sum: 00232 double x = cos(angle * M_PI / 180.0); 00233 double y = sin(angle * M_PI / 180.0); 00234 x += cos(other.angle * M_PI / 180.0) * otherlen; 00235 y += sin(other.angle * M_PI / 180.0) * otherlen; 00236 00237 angle = atan2(y, x) * 180.0 / M_PI; 00238 fixValue(); // atan2 returns value between -PI and PI inclusive 00239 } 00240 00241 // ###################################################################### 00242 inline bool Angle::operator<(const Angle& other) const 00243 { return (angle < other.angle); } 00244 00245 // ###################################################################### 00246 inline bool Angle::operator>(const Angle& other) const 00247 { return (angle > other.angle); } 00248 00249 // ###################################################################### 00250 inline bool Angle::operator!=(const Angle& other) const 00251 { return (angle != other.angle); } 00252 00253 // ###################################################################### 00254 inline bool Angle::operator<(const double other) const 00255 { return (angle < other); } 00256 00257 // ###################################################################### 00258 inline bool Angle::operator>(const double other) const 00259 { return (angle > other); } 00260 00261 // ###################################################################### 00262 inline bool Angle::operator!=(const double other) const 00263 { return (angle != other); } 00264 00265 // ###################################################################### 00266 inline void Angle::fixValue() 00267 { 00268 while (angle <= -180.0) angle += 360.0; 00269 while (angle > 180.0) angle -= 360.0; 00270 } 00271 00272 00273 00274 00275 // ###################################################################### 00276 // ##### Free functions that manipulate angles: 00277 // ###################################################################### 00278 inline Angle averageVectorAngle(std::deque<Angle>::const_iterator astart, 00279 std::deque<Angle>::const_iterator aend) 00280 { 00281 double x = 0.0, y = 0.0; 00282 for (std::deque<Angle>::const_iterator i = astart; i != aend; i ++) 00283 { 00284 double a = i->getVal(); 00285 x += cos(a * M_PI / 180.0); 00286 y += sin(a * M_PI / 180.0); 00287 } 00288 return Angle(atan2(y, x) * 180.0 / M_PI); 00289 } 00290 00291 // ###################################################################### 00292 inline Angle averageVectorAngle(std::deque<Angle>::const_iterator astart, 00293 std::deque<Angle>::const_iterator aend, 00294 const double factor) 00295 { 00296 double x = 0.0, y = 0.0; double len = 1.0; 00297 for (std::deque<Angle>::const_iterator i = astart; i != aend; i ++) 00298 { 00299 double a = i->getVal(); 00300 x += cos(a * M_PI / 180.0) * len; 00301 y += sin(a * M_PI / 180.0) * len; 00302 len *= factor; 00303 } 00304 return Angle(atan2(y, x) * 180.0 / M_PI); 00305 } 00306 00307 #endif 00308 00309 // ###################################################################### 00310 /* So things look consistent in everyone's emacs... */ 00311 /* Local Variables: */ 00312 /* indent-tabs-mode: nil */ 00313 /* End: */