- Main Page
- Related Pages
- Classes
- Files

# _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     ** Conversion Classes
    00250     */
    00251
    00252     class radians;
    00253     class degrees;
    00254     class rotations;
    00255
    00256     /*
    00257     ** Trigonometric 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