X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=ETL%2FETL%2F_fastangle.h;fp=ETL%2FETL%2F_fastangle.h;h=322a8cd5544aaa55427a4fd82f68b4d99919fef9;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/ETL/ETL/_fastangle.h b/ETL/ETL/_fastangle.h new file mode 100644 index 0000000..322a8cd --- /dev/null +++ b/ETL/ETL/_fastangle.h @@ -0,0 +1,461 @@ +/*! ======================================================================== +** Extended Template and Library +** Fast fastangle Abstraction Class Implementation +** $Id$ +** +** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** === N O T E S =========================================================== +** +** This is an internal header file, included by other ETL headers. +** You should not attempt to use it directly. +** +** ========================================================================= */ + +/* === S T A R T =========================================================== */ + +#ifndef __ETL__FASTANGLE_H +#define __ETL__FASTANGLE_H + +/* === H E A D E R S ======================================================= */ + +#include +#include + +#include "_fastangle_tables.h" + +/* === M A C R O S ========================================================= */ + +#ifndef PI +# define PI (3.1415926535897932384626433832795029L) +#endif + +#define ETL_FASTANGLE_INIT() + +/* === T Y P E D E F S ===================================================== */ + +/* === C L A S S E S & S T R U C T S ======================================= */ + +_ETL_BEGIN_NAMESPACE + +/*! ======================================================================== +** \class fastangle +** \brief Optimized abstraction of the concept of an angle +** +** A more detailed description needs to be written. +*/ +class fastangle +{ +public: + typedef double value_type; + +protected: + typedef fixed_base unit; + + unit v; //! Stored in rotations + +public: + + /* + ** Arithmetic Operators + */ + + //! fastangle Addition Operator + fastangle + operator+(const fastangle &rhs)const + { + fastangle ret; + ret.v=v+rhs.v; + return ret; + } + + //! fastangle Subtraction Operator + /*! \sa fastangle dist(const fastangle &) */ + fastangle + operator-(const fastangle &rhs)const + { + fastangle ret; + ret.v=v-rhs.v; + return ret; + } + + //! fastangle Scalar Multiplication Operator + /*! This operator will multiply the given + fastangle by the given scalar value. */ + fastangle + operator*(const unit &rhs)const + { + fastangle ret; + ret.v=v*rhs; + return ret; + } + + fastangle + operator/(const unit &rhs)const + { + fastangle ret; + ret.v=v/rhs; + return ret; + } + + const fastangle & + operator+=(const fastangle &rhs) + { + v+=rhs.v; + return *this; + } + + const fastangle & + operator-=(const fastangle &rhs) + { + v-=rhs.v; + return *this; + } + + const fastangle & + operator*=(const unit &rhs) + { + v*=rhs; + return *this; + } + + const fastangle & + operator/=(const unit &rhs) + { + v/=rhs; + return *this; + } + + //! fastangle Negation + fastangle + operator-()const + { + fastangle ret; + ret.v=-v; + return ret; + } + + //! 180 degree rotation operator + /*! Returns the fastangle directly opposite of + the given fastangle, and will yield a result + between 0 and 2PI */ + fastangle + operator~()const + { + fastangle ret; + ret.v=(unit)std::floor(v+0.5f); + return ret; + } + + /*! Returns true if the shortest + fastangle between the left-hand and + right-hand side is clockwise */ + bool + operator<(const fastangle &rhs)const + { return v(const fastangle &rhs)const + { return v>rhs.v; } +// { return dist(rhs).v>(value_type)0.0; } + + /*! Returns true if the shortest + fastangle between the left-hand and + right-hand side is clockwise, + or if the angles are refer to the same + point on the unit circle. */ + bool + operator<=(const fastangle &rhs)const + { return v<=rhs.v; } +// { return dist(rhs).v<=(value_type)0.0; } + + /*! Returns true if the shortest + fastangle between the left-hand and + right-hand side is counter-clockwise, + or if the angles are refer to the same + point on the unit circle. */ + bool + operator>=(const fastangle &rhs)const + { return v>=rhs.v; } +// { return dist(rhs).v>=(value_type)0.0; } + + /*! Returns true if the angles + are refer to the same point + on the unit circle. */ + bool + operator==(const fastangle &rhs)const + { return v==rhs.v; } +// { return dist(rhs).v==(value_type)0.0; } + + /*! Returns false if the angles + are refer to the same point + on the unit circle. */ + bool + operator!=(const fastangle &rhs)const + { return v!=rhs.v; } +// { return dist(rhs).v!=(value_type)0.0; } + + //! fastangle Difference Function + /*! This function will return the + shortest physical distance between + two angles, from -PI/2 to PI/2 + \warning Not yet tested + \sa fastangle operator-(const fastangle &) */ + fastangle + dist(const fastangle &rhs)const + { + fastangle ret; + ret.v=v-rhs.v; + ret.v-=(unit)std::floor(ret.v+0.5f); + return ret; + } + + //! Rotation Modulus + /*! This function will return the + value of the fastangle between 0 and 2PI */ + fastangle + mod()const + { + fastangle ret(*this); + ret.v-=(unit)std::floor(ret.v); + return ret; + } + + static fastangle + zero() + { + fastangle ret; + ret.v=0; + return ret; + } + + bool operator!()const { return v==unit(0); } + + /* + ** Conversion Classes + */ + + class radians; + class degrees; + class rotations; + + /* + ** Trigonometric Classes + */ + + class sin; + class cos; + class tan; + + /* + ** Friend classes + */ + + friend class radians; + friend class degrees; + friend class rotations; + friend class sin; + friend class cos; + friend class tan; + + /* + ** Bleh... + */ + + typedef radians rad; + typedef degrees deg; + typedef rotations rot; + +}; // END of class fastangle + +/*! ======================================================================== +** \class fastangle::radians +** \brief fastangle representation in radians +** +** A more detailed description needs to be written. +*/ +class fastangle::radians : public fastangle +{ +public: + radians(const value_type &x) { v=x/((value_type)PI*2.0f); } + radians(const fastangle &a):fastangle(a) { } + radians mod()const { return fastangle::mod(); } + radians dist(const fastangle &rhs)const { return fastangle::dist(rhs); } + operator value_type()const { return get(); } + value_type get()const { return (value_type)v*(value_type)PI*2.0f; } +}; // END of class fastangle::radians + +/*! ======================================================================== +** \class fastangle::degrees +** \brief fastangle representation in degrees +** +** A more detailed description needs to be written. +*/ +class fastangle::degrees : public fastangle +{ +public: + degrees(const value_type &x) { v=x/360; } + degrees(const fastangle &a):fastangle(a) { } + degrees mod()const { return fastangle::mod(); } + degrees dist(const fastangle &rhs)const { return fastangle::dist(rhs); } + operator value_type()const { return get(); } + value_type get()const { return v*360/*(value_type)(v-::floor(v))*360*/; } +}; // END of class fastangle::degrees + +/*! ======================================================================== +** \class fastangle::rotations +** \brief fastangle representation in rotations +** +** A more detailed description needs to be written. +*/ +class fastangle::rotations : public fastangle +{ +public: + rotations(const value_type &x) { v=x; } + rotations(const fastangle &a):fastangle(a) { } + rotations mod()const { return fastangle::mod(); } + rotations dist(const fastangle &rhs)const { return fastangle::dist(rhs); } + operator value_type()const { return get(); } + value_type get()const { return v; } +}; // END of class fastangle::rotations + +/*! ======================================================================== +** \class fastangle::sin +** \brief fastangle representation as a sine function +** +** A more detailed description needs to be written. +*/ +class fastangle::sin : public fastangle +{ +public: + sin(const value_type &x) { v.data()=_fastangle_asin_table[(int)((x+1)*(value_type)(1<<(ETL_FASTANGLE_LOOKUP_RES-1)))]; } + sin(const fastangle &a):fastangle(a) { } + sin mod()const { return fastangle::mod(); } + sin dist(const fastangle &rhs)const { return fastangle::dist(rhs); } + operator value_type()const { return get(); } + value_type get()const { return (value_type)_fastangle_sin_table[v.data()&( (1<1) + 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))]; + else if(x<-1) + 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))]; + else + v.data()=_fastangle_atan_table[(int)((x+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]; + } + + tan(const value_type &y,const value_type &x) + { + if(x>=0 && y>=0) // First quadrant + { + if(y>x) + v.data()=(1<<(ETL_FASTANGLE_LOOKUP_RES-2))-_fastangle_atan_table[(int)(((x/y)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]; + else + v.data()=_fastangle_atan_table[(int)(((y/x)+1)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]; + } + else if(x>=0 && y<0) // Fourth quadrant + { + if(-y>x) + 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))]; + else + v.data()=_fastangle_atan_table[(int)(((y/x)+1.0)*(value_type)((1<<(ETL_FASTANGLE_LOOKUP_RES-1))-1))]; + } + else if(x<0 && y>=0) // Second quadrant + { + if(y>-x) + 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))]; + else + 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)); + } + else if(x<0 && y<0) // Third Quadrant + { + if(-y>-x) + 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)); + else + 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)); + } + else v.data()=0; + } + tan(const fastangle &a):fastangle(a) { } + tan mod()const { return fastangle::mod(); } + tan dist(const fastangle &rhs)const { return fastangle::dist(rhs); } + operator value_type()const { return get(); } + value_type get()const { return (value_type)_fastangle_tan_table[v.data()&( (1< +struct affine_combo +{ + etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b,const float &t)const + { + return b.dist(a)*t+a; + } + + etl::fastangle reverse(const etl::fastangle &x, const etl::fastangle &b, const float &t)const + { + return x.dist(b*t)*((float)1/((float)1-t)); + } +}; + +template <> +struct distance_func : public std::binary_function +{ + etl::fastangle operator()(const etl::fastangle &a,const etl::fastangle &b)const + { + etl::fastangle delta=b.dist(a); + if(delta