_angle.h

Go to the documentation of this file.
00001 #include <stdio.h>
00002 /* ========================================================================
00003 ** Extended Template and Library
00004 ** Angle Abstraction Class Implementation
00005 ** $Id: _angle.h 848 2007-10-06 02:25:36Z dooglus $
00006 **
00007 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
00008 ** Copyright (c) 2007 Chris Moore
00009 **
00010 ** This package is free software; you can redistribute it and/or
00011 ** modify it under the terms of the GNU General Public License as
00012 ** published by the Free Software Foundation; either version 2 of
00013 ** the License, or (at your option) any later version.
00014 **
00015 ** This package is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 ** General Public License for more details.
00019 **
00020 ** === N O T E S ===========================================================
00021 **
00022 ** This is an internal header file, included by other ETL headers.
00023 ** You should not attempt to use it directly.
00024 **
00025 ** ========================================================================= */
00026 
00027 /* === S T A R T =========================================================== */
00028 
00029 #ifndef __ETL_ANGLE_H
00030 #define __ETL_ANGLE_H
00031 
00032 /* === H E A D E R S ======================================================= */
00033 
00034 #include <cmath>
00035 #include <functional>
00036 
00037 /* === M A C R O S ========================================================= */
00038 
00039 #ifndef PI
00040 # define PI (3.1415926535897932384626433832795029L)
00041 # define HALF_PI (PI/2)
00042 #endif
00043 
00044 #define ANGLE_EPSILON (1.0e-6)
00045 
00046 /* === T Y P E D E F S ===================================================== */
00047 
00048 /* === C L A S S E S & S T R U C T S ======================================= */
00049 
00050 _ETL_BEGIN_NAMESPACE
00051 
00052 // ========================================================================
00058 class angle
00059 {
00060 public:
00061     typedef float value_type;
00062 
00063 protected:
00064     typedef value_type unit;
00065 
00066     unit v; 
00067 
00068 public:
00069 
00070     /*
00071     ** Arithmetic Operators
00072     */
00073 
00074     const angle &
00075     operator+=(const angle &rhs)
00076     { v+=rhs.v; return *this; }
00077 
00078     const angle &
00079     operator-=(const angle &rhs)
00080     { v-=rhs.v; return *this; }
00081 
00082     const angle &
00083     operator*=(const unit &rhs)
00084     { v*=rhs; return *this; }
00085 
00086     const angle &
00087     operator/=(const unit &rhs)
00088     { v/=rhs; return *this; }
00089 
00091     angle
00092     operator+(const angle &rhs)const
00093     { return angle(*this)+=rhs; }
00094 
00096 
00097     angle
00098     operator-(const angle &rhs)const
00099     { return angle(*this)-=rhs; }
00100 
00102 
00104     angle
00105     operator*(const unit &rhs)const
00106     { return angle(*this)*=rhs; }
00107 
00108     angle
00109     operator/(const unit &rhs)const
00110     { return angle(*this)/=rhs; }
00111 
00113     angle
00114     operator-()const
00115     {
00116         angle ret;
00117         ret.v=-v;
00118         return ret;
00119     }
00120 
00122 
00125     angle
00126     operator~()const
00127     {
00128         angle ret;
00129         ret.v = v+PI;
00130         return ret.mod();
00131     }
00132 
00136     bool
00137     operator<(const angle &rhs)const
00138     { return dist(rhs).v<(value_type)0.0; }
00139 
00143     bool
00144     operator>(const angle &rhs)const
00145     { return dist(rhs).v>(value_type)0.0; }
00146 
00152     bool
00153     operator<=(const angle &rhs)const
00154     { return dist(rhs).v<=(value_type)0.0; }
00155 
00161     bool
00162     operator>=(const angle &rhs)const
00163     { return dist(rhs).v>=(value_type)0.0; }
00164 
00168     bool
00169     operator==(const angle &rhs)const
00170     { return std::abs(dist(rhs).v)<ANGLE_EPSILON; }
00171 
00175     bool
00176     operator!=(const angle &rhs)const
00177     { return std::abs(dist(rhs).v)>ANGLE_EPSILON; }
00178 
00180 
00182     angle
00183     abs()const
00184     {
00185         angle ret;
00186         ret.v=std::abs(v);
00187         return ret;
00188     }
00189 
00191 
00195     angle
00196     dist(const angle &rhs)const
00197     {
00198         angle ret;
00199         ret.v=v-rhs.v;
00200         ret.v-=rot_floor(ret.v+PI);
00201         return ret;
00202     }
00203 
00205 
00207     angle
00208     mod()const
00209     {
00210         angle ret(*this);
00211         ret.v-=rot_floor(ret.v);
00212         return ret;
00213     }
00214 
00216     static angle
00217     zero()
00218     {
00219         angle ret;
00220         ret.v=0;
00221         return ret;
00222     }
00223 
00225     static angle
00226     one()
00227     {
00228         angle ret;
00229         ret.v=PI*2;
00230         return ret;
00231     }
00232 
00234     static angle
00235     half()
00236     {
00237         angle ret;
00238         ret.v=PI;
00239         return ret;
00240     }
00241 
00242     bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; }
00243 
00244 private:
00245 
00246     static value_type rot_floor(value_type x)
00247     { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
00248 
00249 public:
00250     /*
00251     ** Conversion Classes
00252     */
00253 
00254     class rad;
00255     class deg;
00256     class rot;
00257 
00258     /*
00259     ** Trigonometric Classes
00260     */
00261 
00262     class sin;
00263     class cos;
00264     class tan;
00265 
00266     /*
00267     ** Friend classes
00268     */
00269 
00270     friend class rad;
00271     friend class deg;
00272     friend class rot;
00273     friend class sin;
00274     friend class cos;
00275     friend class tan;
00276 
00277     /*
00278     ** Deprecated
00279     */
00280 
00281 #ifndef ETL_NO_DEPRECATED
00282     typedef rad     radians;
00283     typedef deg     degrees;
00284     typedef rot     rotations;
00285 #endif
00286 }; // END of class angle
00287 
00288 // ========================================================================
00294 class angle::rad : public angle
00295 {
00296 public:
00297     explicit rad(const value_type &x) { v=x; }
00298     rad(const angle &a):angle(a) { }
00299     rad mod()const { return angle::mod(); }
00300     rad dist(const angle &rhs)const { return angle::dist(rhs); }
00301     value_type get()const { return v; }
00302 #ifndef ETL_NO_DEPRECATED
00303     // operator value_type()const ETL_DEPRECATED_FUNCTION;
00304 #endif
00305 }; // END of class angle::radians
00306 // inline angle::rad::operator angle::value_type()const { return get(); }
00307 
00308 // ========================================================================
00314 class angle::deg : public angle
00315 {
00316 public:
00317     explicit deg(const value_type &x) { v=x*((PI*2)/360); }
00318     deg(const angle &a):angle(a) { }
00319     deg mod()const { return angle::mod(); }
00320     deg dist(const angle &rhs)const { return angle::dist(rhs); }
00321     value_type get()const { return v*360/(PI*2); }
00322 #ifndef ETL_NO_DEPRECATED
00323     // operator value_type()const ETL_DEPRECATED_FUNCTION;
00324 #endif
00325 }; // END of class angle::degrees
00326 // inline angle::deg::operator angle::value_type()const { return get(); }
00327 
00328 // ========================================================================
00334 class angle::rot : public angle
00335 {
00336 public:
00337     explicit rot(const value_type &x) { v=x*(PI*2); }
00338     rot(const angle &a):angle(a) { }
00339     rot mod()const { return angle::mod(); }
00340     rot dist(const angle &rhs)const { return angle::dist(rhs); }
00341     value_type get()const { return v/(PI*2); }
00342 #ifndef ETL_NO_DEPRECATED
00343     // operator value_type()const ETL_DEPRECATED_FUNCTION;
00344 #endif
00345 }; // END of class angle::rotations
00346 // inline angle::rot::operator angle::value_type()const { return get(); }
00347 
00348 // ========================================================================
00354 class angle::sin : public angle
00355 {
00356 public:
00357     explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
00358     sin(const angle &a):angle(a) { }
00359     sin mod()const { return angle::mod(); }
00360     sin dist(const angle &rhs)const { return angle::dist(rhs); }
00361     value_type get()const { return static_cast<value_type>(std::sin(v)); }
00362 #ifndef ETL_NO_DEPRECATED
00363     // operator value_type()const ETL_DEPRECATED_FUNCTION;
00364 #endif
00365 }; // END of class angle::sin
00366 // inline angle::sin::operator angle::value_type()const { return get(); }
00367 
00368 // ========================================================================
00374 class angle::cos : public angle
00375 {
00376 public:
00377     explicit cos(const value_type &x)   { v=(value_type)(std::acos(x)); }
00378     cos(const angle &a):angle(a) { }
00379     cos mod()const { return angle::mod(); }
00380     cos dist(const angle &rhs)const { return angle::dist(rhs); }
00381     value_type get()const { return (value_type)std::cos(v); }
00382 #ifndef ETL_NO_DEPRECATED
00383     // operator value_type()const ETL_DEPRECATED_FUNCTION;
00384 #endif
00385 }; // END of class angle::cos
00386 // inline angle::cos::operator angle::value_type()const { return get(); }
00387 
00388 // ========================================================================
00394 class angle::tan : public angle
00395 {
00396 public:
00397     explicit tan(const value_type &x)   { v=(value_type)(std::atan(x)); }
00398     tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
00399     tan(const angle &a):angle(a) { }
00400     tan mod()const { return angle::mod(); }
00401     tan dist(const angle &rhs)const { return angle::dist(rhs); }
00402     value_type get()const { return (value_type)std::tan(v); }
00403 #ifndef ETL_NO_DEPRECATED
00404     // operator value_type()const ETL_DEPRECATED_FUNCTION;
00405 #endif
00406 }; // END of class angle::tan
00407 // inline angle::tan::operator angle::value_type()const { return get(); }
00408 
00409 _ETL_END_NAMESPACE
00410 
00411 //#include <iostream>
00412 
00413 template <typename T>
00414 struct affine_combo<etl::angle, T>
00415 {
00416     typedef T time_type;
00417 
00418     //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
00419     //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
00420 
00421     etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
00422     {
00423         return b.dist(a)*(float)t+a;
00424     }
00425 
00426     etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
00427     {
00428         return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
00429     }
00430 };
00431 
00432 template <>
00433 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
00434 {
00435     etl::angle operator()(const etl::angle &a,const etl::angle &b)const
00436     {
00437         etl::angle delta=b.dist(a);
00438         //if(delta<etl::angle::zero())
00439         //  return delta+etl::angle::one();
00440         return delta;
00441     }
00442 
00443     etl::angle cook(const etl::angle &x)const { return x; }
00444     etl::angle uncook(const etl::angle &x)const { return x; }
00445 };
00446 
00447 /* === E N D =============================================================== */
00448 
00449 #endif

Generated on Sun Oct 28 03:51:05 2007 for ETL by  doxygen 1.5.3-20071008