_fastangle.h

Go to the documentation of this file.
00001 
00025 /* === S T A R T =========================================================== */
00026 
00027 #ifndef __ETL_FASTANGLE_H
00028 #define __ETL_FASTANGLE_H
00029 
00030 /* === H E A D E R S ======================================================= */
00031 
00032 #include <cmath>
00033 #include <ETL/fixed>
00034 
00035 #include "_fastangle_tables.h"
00036 
00037 /* === M A C R O S ========================================================= */
00038 
00039 #ifndef PI
00040 # define PI (3.1415926535897932384626433832795029L)
00041 #endif
00042 
00043 #define ETL_FASTANGLE_INIT()
00044 
00045 /* === T Y P E D E F S ===================================================== */
00046 
00047 /* === C L A S S E S & S T R U C T S ======================================= */
00048 
00049 _ETL_BEGIN_NAMESPACE
00050 
00057 class fastangle
00058 {
00059 public:
00060     typedef double value_type;
00061 
00062 protected:
00063     typedef fixed_base<ETL_FIXED_TYPE,ETL_FASTANGLE_LOOKUP_RES> unit;
00064 
00065     unit v; 
00066     
00067 public:
00068     
00069     /*
00070     ** Arithmetic Operators
00071     */
00072 
00074     fastangle
00075     operator+(const fastangle &rhs)const
00076     {
00077         fastangle ret;
00078         ret.v=v+rhs.v;
00079         return ret;
00080     }
00081 
00083 
00084     fastangle
00085     operator-(const fastangle &rhs)const
00086     {
00087         fastangle ret;
00088         ret.v=v-rhs.v;
00089         return ret;
00090     }
00091 
00093 
00095     fastangle
00096     operator*(const unit &rhs)const
00097     {
00098         fastangle ret;
00099         ret.v=v*rhs;
00100         return ret;
00101     }
00102 
00103     fastangle
00104     operator/(const unit &rhs)const
00105     {
00106         fastangle ret;
00107         ret.v=v/rhs;
00108         return ret;
00109     }
00110     
00111     const fastangle &
00112     operator+=(const fastangle &rhs)
00113     {
00114         v+=rhs.v;
00115         return *this;
00116     }
00117 
00118     const fastangle &
00119     operator-=(const fastangle &rhs)
00120     {
00121         v-=rhs.v;
00122         return *this;
00123     }
00124 
00125     const fastangle &
00126     operator*=(const unit &rhs)
00127     {
00128         v*=rhs;
00129         return *this;
00130     }
00131 
00132     const fastangle &
00133     operator/=(const unit &rhs)
00134     {
00135         v/=rhs;
00136         return *this;
00137     }
00138 
00140     fastangle
00141     operator-()const
00142     {
00143         fastangle ret;
00144         ret.v=-v;
00145         return ret;
00146     }
00147     
00149 
00152     fastangle
00153     operator~()const
00154     {
00155         fastangle ret;
00156         ret.v=(unit)std::floor(v+0.5f);
00157         return ret;
00158     }
00159 
00163     bool
00164     operator<(const fastangle &rhs)const
00165     { return v<rhs.v; }
00166 //  { return dist(rhs).v<(value_type)0.0; }
00167 
00171     bool
00172     operator>(const fastangle &rhs)const
00173     { return v>rhs.v; }
00174 //  { return dist(rhs).v>(value_type)0.0; }
00175 
00181     bool
00182     operator<=(const fastangle &rhs)const
00183     { return v<=rhs.v; }
00184 //  { return dist(rhs).v<=(value_type)0.0; }
00185 
00191     bool
00192     operator>=(const fastangle &rhs)const
00193     { return v>=rhs.v; }
00194 //  { return dist(rhs).v>=(value_type)0.0; }
00195 
00199     bool
00200     operator==(const fastangle &rhs)const
00201     { return v==rhs.v; }
00202 //  { return dist(rhs).v==(value_type)0.0; }
00203 
00207     bool
00208     operator!=(const fastangle &rhs)const
00209     { return v!=rhs.v; }
00210 //  { return dist(rhs).v!=(value_type)0.0; }
00211 
00213 
00218     fastangle
00219     dist(const fastangle &rhs)const
00220     {
00221         fastangle ret;
00222         ret.v=v-rhs.v;
00223         ret.v-=(unit)std::floor(ret.v+0.5f);
00224         return ret;
00225     }
00226 
00228 
00230     fastangle
00231     mod()const
00232     {
00233         fastangle ret(*this);
00234         ret.v-=(unit)std::floor(ret.v);
00235         return ret;
00236     }
00237 
00238     static fastangle
00239     zero()
00240     {
00241         fastangle ret;
00242         ret.v=0;
00243         return ret;
00244     }
00245 
00246     bool operator!()const { return v==unit(0); }
00247 
00248     /*
00249     ** Converstion Classes
00250     */
00251 
00252     class radians;
00253     class degrees;
00254     class rotations;
00255 
00256     /*
00257     ** Trigometric Classes
00258     */
00259 
00260     class sin;
00261     class cos;
00262     class tan; 
00263 
00264     /*
00265     ** Friend classes
00266     */
00267 
00268     friend class radians;
00269     friend class degrees;
00270     friend class rotations;
00271     friend class sin;
00272     friend class cos;
00273     friend class tan;
00274 
00275     /*
00276     ** Bleh...
00277     */
00278 
00279     typedef radians     rad;
00280     typedef degrees     deg;
00281     typedef rotations   rot;
00282 
00283 }; // END of class fastangle
00284 
00291 class fastangle::radians : public fastangle
00292 {
00293 public:
00294     radians(const value_type &x) { v=x/((value_type)PI*2.0f); }
00295     radians(const fastangle &a):fastangle(a) { }
00296     radians mod()const { return fastangle::mod(); }
00297     radians dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
00298     operator value_type()const { return get(); }
00299     value_type get()const { return (value_type)v*(value_type)PI*2.0f; }
00300 }; // END of class fastangle::radians
00301 
00308 class fastangle::degrees : public fastangle
00309 {
00310 public:
00311     degrees(const value_type &x) { v=x/360; }
00312     degrees(const fastangle &a):fastangle(a) { }
00313     degrees mod()const { return fastangle::mod(); }
00314     degrees dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
00315     operator value_type()const { return get(); }
00316     value_type get()const { return v*360/*(value_type)(v-::floor(v))*360*/; }
00317 }; // END of class fastangle::degrees
00318 
00325 class fastangle::rotations : public fastangle
00326 {
00327 public:
00328     rotations(const value_type &x) { v=x; }
00329     rotations(const fastangle &a):fastangle(a) { }
00330     rotations mod()const { return fastangle::mod(); }
00331     rotations dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
00332     operator value_type()const { return get(); }
00333     value_type get()const { return v; }
00334 }; // END of class fastangle::rotations
00335 
00342 class fastangle::sin : public fastangle
00343 {
00344 public:
00345     sin(const value_type &x)    { v.data()=_fastangle_asin_table[(int)((x+1)*(value_type)(1<<(ETL_FASTANGLE_LOOKUP_RES-1)))]; }
00346     sin(const fastangle &a):fastangle(a) { }
00347     sin mod()const { return fastangle::mod(); }
00348     sin dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
00349     operator value_type()const { return get(); }
00350     value_type get()const { return (value_type)_fastangle_sin_table[v.data()&( (1<<ETL_FASTANGLE_LOOKUP_RES)-1)]; }
00351 }; // END of class fastangle::sin
00352 
00359 class fastangle::cos : public fastangle
00360 {
00361 public:
00362     cos(const value_type &x)    { v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_asin_table[(int)((x+1)*(value_type)(1<<(ETL_FASTANGLE_LOOKUP_RES-1)))]; }
00363     cos(const fastangle &a):fastangle(a) { }
00364     cos mod()const { return fastangle::mod(); }
00365     cos dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
00366     operator value_type()const { return get(); }
00367     value_type get()const { return (value_type)_fastangle_sin_table[(v.data()+(1<<(ETL_FASTANGLE_LOOKUP_RES-2)))&( (1<<ETL_FASTANGLE_LOOKUP_RES)-1)]; }
00368 }; // END of class fastangle::cos
00369 
00376 class fastangle::tan : public fastangle
00377 {
00378 public:
00379     tan(const value_type &x)
00380     {
00381         if(x>1)
00382             v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((1.0/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00383         else if(x<-1)
00384             v.data()=-(1<<(ETL_FASTANGLE_LOOKUP_RES-1)) + (1<<(ETL_FASTANGLE_LOOKUP_RES-2)) - _fastangle_atan_table[(int)(((1.0/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00385         else
00386             v.data()=_fastangle_atan_table[(int)((x+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00387     }
00388     
00389     tan(const value_type &y,const value_type &x)
00390     {
00391         if(x>=0 && y>=0) // First quadrant
00392         {
00393             if(y>x)
00394                 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00395             else
00396                 v.data()=_fastangle_atan_table[(int)(((y/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00397         }
00398         else if(x>=0 && y<0) // Fourth quadrant
00399         {
00400             if(-y>x)
00401                 v.data()=-(1<<(ETL_FASTANGLE_LOOKUP_RES-1)) + (1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00402             else
00403                 v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00404         }
00405         else if(x<0 && y>=0) // Second quadrant
00406         {
00407             if(y>-x)
00408                 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))];
00409             else
00410                 v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]+(1<<(ETL_FASTANGLE_LOOKUP_RES-1));
00411         }
00412         else if(x<0 && y<0) // Third Quadrant
00413         {
00414             if(-y>-x)
00415                 v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))] - (1<<(ETL_FASTANGLE_LOOKUP_RES-1));
00416             else
00417                 v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]-(1<<(ETL_FASTANGLE_LOOKUP_RES-1));
00418         }
00419         else v.data()=0;
00420     }
00421     tan(const fastangle &a):fastangle(a) { }
00422     tan mod()const { return fastangle::mod(); }
00423     tan dist(const fastangle &rhs)const { return fastangle::dist(rhs); }
00424     operator value_type()const { return get(); }
00425     value_type get()const { return (value_type)_fastangle_tan_table[v.data()&( (1<<ETL_FASTANGLE_LOOKUP_RES)-1)]; }
00426 }; // END of class fastangle::tan
00427 
00428 _ETL_END_NAMESPACE
00429 
00430 template <>
00431 struct affine_combo<etl::fastangle,float>
00432 {
00433     etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b,const float &t)const
00434     {
00435         return b.dist(a)*t+a;
00436     }
00437 
00438     etl::fastangle reverse(const etl::fastangle &x, const etl::fastangle &b, const float &t)const
00439     {
00440         return x.dist(b*t)*((float)1/((float)1-t));
00441     }
00442 };
00443 
00444 template <>
00445 struct distance_func<etl::fastangle> : public std::binary_function<etl::fastangle, etl::fastangle, etl::fastangle>
00446 {
00447     etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b)const
00448     {
00449         etl::fastangle delta=b.dist(a);
00450         if(delta<etl::fastangle::zero())
00451             return -delta;
00452         return delta;
00453     }
00454     
00455     etl::fastangle cook(const etl::fastangle &x) { return x; }
00456     etl::fastangle uncook(const etl::fastangle &x) { return x; }
00457 };
00458 
00459 /* === E N D =============================================================== */
00460 
00461 #endif

Generated on Sat Nov 4 11:29:20 2006 for ETL by  doxygen 1.4.7