- Main Page
- Related Pages
- Classes
- Files

# _angle.h

Go to the documentation of this file.

    00001 /* ========================================================================
    00002 ** Extended Template and Library
    00003 ** Angle Abstraction Class Implementation
    00004 ** $Id$
    00005 **
    00006 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
    00007 ** Copyright (c) 2007 Chris Moore
    00008 **
    00009 ** This package is free software; you can redistribute it and/or
    00010 ** modify it under the terms of the GNU General Public License as
    00011 ** published by the Free Software Foundation; either version 2 of
    00012 ** the License, or (at your option) any later version.
    00013 **
    00014 ** This package is distributed in the hope that it will be useful,
    00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00017 ** General Public License for more details.
    00018 **
    00019 ** === N O T E S ===========================================================
    00020 **
    00021 ** This is an internal header file, included by other ETL headers.
    00022 ** You should not attempt to use it directly.
    00023 **
    00024 ** ========================================================================= */
    00025
    00026 /* === S T A R T =========================================================== */
    00027
    00028 #ifndef __ETL__ANGLE_H
    00029 #define __ETL__ANGLE_H
    00030
    00031 /* === H E A D E R S ======================================================= */
    00032
    00033 #include <cstdio>
    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
    00121 #ifdef ETL_NOT_USED
    00123
    00126     angle
    00127     operator~()const
    00128     {
    00129         angle ret;
    00130         ret.v = v+PI;
    00131         return ret.mod();
    00132     }
    00133 #endif // ETL_NOT_USED
    00134
    00135 #ifdef ETL_WRAP_ANGLES
    00136
    00139     bool
    00140     operator<(const angle &rhs)const
    00141     { return dist(rhs).v<(value_type)0.0; }
    00142
    00146     bool
    00147     operator>(const angle &rhs)const
    00148     { return dist(rhs).v>(value_type)0.0; }
    00149
    00155     bool
    00156     operator<=(const angle &rhs)const
    00157     { return dist(rhs).v<=(value_type)0.0; }
    00158
    00164     bool
    00165     operator>=(const angle &rhs)const
    00166     { return dist(rhs).v>=(value_type)0.0; }
    00167
    00171     bool
    00172     operator==(const angle &rhs)const
    00173     { return std::abs(dist(rhs).v)<ANGLE_EPSILON; }
    00174
    00178     bool
    00179     operator!=(const angle &rhs)const
    00180     { return std::abs(dist(rhs).v)>ANGLE_EPSILON; }
    00181 #else // ETL_WRAP_ANGLES
    00182
    00185     bool
    00186     operator<(const angle &rhs)const
    00187     { return v < rhs.v; }
    00188
    00192     bool
    00193     operator>(const angle &rhs)const
    00194     { return v > rhs.v; }
    00195
    00199     bool
    00200     operator<=(const angle &rhs)const
    00201     { return v <= rhs.v; }
    00202
    00206     bool
    00207     operator>=(const angle &rhs)const
    00208     { return v >= rhs.v; }
    00209
    00212     bool
    00213     operator==(const angle &rhs)const
    00214     { return std::abs(v - rhs.v)<ANGLE_EPSILON; }
    00215
    00218     bool
    00219     operator!=(const angle &rhs)const
    00220         { return std::abs(v - rhs.v)>ANGLE_EPSILON; }
    00221 #endif // ETL_WRAP_ANGLES
    00222
    00224
    00226     angle
    00227     abs()const
    00228     {
    00229         angle ret;
    00230         ret.v=std::abs(v);
    00231         return ret;
    00232     }
    00233
    00234 #ifdef ETL_WRAP_ANGLES
    00236
    00240     angle
    00241     dist(const angle &rhs)const
    00242     {
    00243         angle ret;
    00244         ret.v=v-rhs.v;
    00245         ret.v-=rot_floor(ret.v+PI);
    00246         return ret;
    00247     }
    00248
    00250
    00252     angle
    00253     mod()const
    00254     {
    00255         angle ret(*this);
    00256         ret.v-=rot_floor(ret.v);
    00257         return ret;
    00258     }
    00259 #else // ETL_WRAP_ANGLES
    00261
    00265     angle
    00266     dist(const angle &rhs)const
    00267     { return angle(*this)-=rhs; }
    00268
    00270
    00272     angle
    00273     mod()const
    00274     {
    00275         angle ret(*this);
    00276         return ret;
    00277     }
    00278 #endif // ETL_WRAP_ANGLES
    00279
    00281     static angle
    00282     zero()
    00283     {
    00284         angle ret;
    00285         ret.v=0;
    00286         return ret;
    00287     }
    00288
    00290     static angle
    00291     one()
    00292     {
    00293         angle ret;
    00294         ret.v=PI*2;
    00295         return ret;
    00296     }
    00297
    00299     static angle
    00300     half()
    00301     {
    00302         angle ret;
    00303         ret.v=PI;
    00304         return ret;
    00305     }
    00306
    00307     bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; }
    00308
    00309 private:
    00310
    00311 #ifdef ETL_WRAP_ANGLES
    00312     static value_type rot_floor(value_type x)
    00313     { return static_cast<value_type>(std::floor(x/(PI*2))*PI*2); }
    00314 #endif // ETL_WRAP_ANGLES
    00315
    00316 public:
    00317     /*
    00318     ** Conversion Classes
    00319     */
    00320
    00321     class rad;
    00322     class deg;
    00323     class rot;
    00324
    00325     /*
    00326     ** Trigonometric Classes
    00327     */
    00328
    00329     class sin;
    00330     class cos;
    00331     class tan;
    00332
    00333     /*
    00334     ** Friend classes
    00335     */
    00336
    00337     friend class rad;
    00338     friend class deg;
    00339     friend class rot;
    00340     friend class sin;
    00341     friend class cos;
    00342     friend class tan;
    00343
    00344     /*
    00345     ** Deprecated
    00346     */
    00347
    00348 #ifndef ETL_NO_DEPRECATED
    00349     typedef rad     radians;
    00350     typedef deg     degrees;
    00351     typedef rot     rotations;
    00352 #endif
    00353 }; // END of class angle
    00354
    00355 // ========================================================================
    00361 class angle::rad : public angle
    00362 {
    00363 public:
    00364     explicit rad(const value_type &x) { v=x; }
    00365     rad(const angle &a):angle(a) { }
    00366     rad mod()const { return angle::mod(); }
    00367     rad dist(const angle &rhs)const { return angle::dist(rhs); }
    00368     value_type get()const { return v; }
    00369 #ifndef ETL_NO_DEPRECATED
    00370     // operator value_type()const ETL_DEPRECATED_FUNCTION;
    00371 #endif
    00372 }; // END of class angle::radians
    00373 // inline angle::rad::operator angle::value_type()const { return get(); }
    00374
    00375 // ========================================================================
    00381 class angle::deg : public angle
    00382 {
    00383 public:
    00384     explicit deg(const value_type &x) { v=x*((PI*2)/360); }
    00385     deg(const angle &a):angle(a) { }
    00386     deg mod()const { return angle::mod(); }
    00387     deg dist(const angle &rhs)const { return angle::dist(rhs); }
    00388     value_type get()const { return v*360/(PI*2); }
    00389 #ifndef ETL_NO_DEPRECATED
    00390     // operator value_type()const ETL_DEPRECATED_FUNCTION;
    00391 #endif
    00392 }; // END of class angle::degrees
    00393 // inline angle::deg::operator angle::value_type()const { return get(); }
    00394
    00395 // ========================================================================
    00401 class angle::rot : public angle
    00402 {
    00403 public:
    00404     explicit rot(const value_type &x) { v=x*(PI*2); }
    00405     rot(const angle &a):angle(a) { }
    00406     rot mod()const { return angle::mod(); }
    00407     rot dist(const angle &rhs)const { return angle::dist(rhs); }
    00408     value_type get()const { return v/(PI*2); }
    00409 #ifndef ETL_NO_DEPRECATED
    00410     // operator value_type()const ETL_DEPRECATED_FUNCTION;
    00411 #endif
    00412 }; // END of class angle::rotations
    00413 // inline angle::rot::operator angle::value_type()const { return get(); }
    00414
    00415 // ========================================================================
    00421 class angle::sin : public angle
    00422 {
    00423 public:
    00424     explicit sin(const value_type &x) { v=static_cast<value_type>(std::asin(x)); }
    00425     sin(const angle &a):angle(a) { }
    00426     sin mod()const { return angle::mod(); }
    00427     sin dist(const angle &rhs)const { return angle::dist(rhs); }
    00428     value_type get()const { return static_cast<value_type>(std::sin(v)); }
    00429 #ifndef ETL_NO_DEPRECATED
    00430     // operator value_type()const ETL_DEPRECATED_FUNCTION;
    00431 #endif
    00432 }; // END of class angle::sin
    00433 // inline angle::sin::operator angle::value_type()const { return get(); }
    00434
    00435 // ========================================================================
    00441 class angle::cos : public angle
    00442 {
    00443 public:
    00444     explicit cos(const value_type &x)   { v=(value_type)(std::acos(x)); }
    00445     cos(const angle &a):angle(a) { }
    00446     cos mod()const { return angle::mod(); }
    00447     cos dist(const angle &rhs)const { return angle::dist(rhs); }
    00448     value_type get()const { return (value_type)std::cos(v); }
    00449 #ifndef ETL_NO_DEPRECATED
    00450     // operator value_type()const ETL_DEPRECATED_FUNCTION;
    00451 #endif
    00452 }; // END of class angle::cos
    00453 // inline angle::cos::operator angle::value_type()const { return get(); }
    00454
    00455 // ========================================================================
    00461 class angle::tan : public angle
    00462 {
    00463 public:
    00464     explicit tan(const value_type &x)   { v=(value_type)(std::atan(x)); }
    00465     tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); }
    00466     tan(const angle &a):angle(a) { }
    00467     tan mod()const { return angle::mod(); }
    00468     tan dist(const angle &rhs)const { return angle::dist(rhs); }
    00469     value_type get()const { return (value_type)std::tan(v); }
    00470 #ifndef ETL_NO_DEPRECATED
    00471     // operator value_type()const ETL_DEPRECATED_FUNCTION;
    00472 #endif
    00473 }; // END of class angle::tan
    00474 // inline angle::tan::operator angle::value_type()const { return get(); }
    00475
    00476 _ETL_END_NAMESPACE
    00477
    00478 //#include <iostream>
    00479
    00480 template <typename T>
    00481 struct affine_combo<etl::angle, T>
    00482 {
    00483     typedef T time_type;
    00484
    00485     //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
    00486     //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
    00487
    00488     etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
    00489     {
    00490         return b.dist(a)*(float)t+a;
    00491     }
    00492
    00493     etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
    00494     {
    00495         return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
    00496     }
    00497 };
    00498
    00499 template <>
    00500 struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
    00501 {
    00502     etl::angle operator()(const etl::angle &a,const etl::angle &b)const
    00503     {
    00504         etl::angle delta=b.dist(a);
    00505         //if(delta<etl::angle::zero())
    00506         //  return delta+etl::angle::one();
    00507         return delta;
    00508     }
    00509
    00510     etl::angle cook(const etl::angle &x)const { return x; }
    00511     etl::angle uncook(const etl::angle &x)const { return x; }
    00512 };
    00513
    00514 /* === E N D =============================================================== */
    00515
    00516 #endif