X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=ETL%2FETL%2F_angle.h;fp=ETL%2FETL%2F_angle.h;h=2ea372099a4b732fc7f9196425b13f1d5687938e;hb=a095981e18cc37a8ecc7cd237cc22b9c10329264;hp=0000000000000000000000000000000000000000;hpb=9459638ad6797b8139f1e9f0715c96076dbf0890;p=synfig.git diff --git a/ETL/ETL/_angle.h b/ETL/ETL/_angle.h new file mode 100644 index 0000000..2ea3720 --- /dev/null +++ b/ETL/ETL/_angle.h @@ -0,0 +1,516 @@ +/* ======================================================================== +** Extended Template and Library +** Angle Abstraction Class Implementation +** $Id$ +** +** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** Copyright (c) 2007 Chris Moore +** +** 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__ANGLE_H +#define __ETL__ANGLE_H + +/* === H E A D E R S ======================================================= */ + +#include +#include +#include + +/* === M A C R O S ========================================================= */ + +#ifndef PI +# define PI (3.1415926535897932384626433832795029L) +# define HALF_PI (PI/2) +#endif + +#define ANGLE_EPSILON (1.0e-6) + +/* === 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 angle _angle.h ETL/angle +** \brief Abstraction of the concept of an angle +** \see angle::deg, angle::rad, angle::rot, angle::sin, angle::cos, angle::tan, fastangle +** \writeme +*/ +class angle +{ +public: + typedef float value_type; + +protected: + typedef value_type unit; + + unit v; //! Stored in radians; positive values indicate counter-clockwise. + +public: + + /* + ** Arithmetic Operators + */ + + const angle & + operator+=(const angle &rhs) + { v+=rhs.v; return *this; } + + const angle & + operator-=(const angle &rhs) + { v-=rhs.v; return *this; } + + const angle & + operator*=(const unit &rhs) + { v*=rhs; return *this; } + + const angle & + operator/=(const unit &rhs) + { v/=rhs; return *this; } + + //! Angle Addition Operator + angle + operator+(const angle &rhs)const + { return angle(*this)+=rhs; } + + //! Angle Subtraction Operator + /*! \sa angle dist(const angle &) */ + angle + operator-(const angle &rhs)const + { return angle(*this)-=rhs; } + + //! Angle Scalar Multiplication Operator + /*! This operator will multiply the given + angle by the given scalar value. */ + angle + operator*(const unit &rhs)const + { return angle(*this)*=rhs; } + + angle + operator/(const unit &rhs)const + { return angle(*this)/=rhs; } + + //! Angle Negation + angle + operator-()const + { + angle ret; + ret.v=-v; + return ret; + } + +#ifdef ETL_NOT_USED + //! 180 degree rotation operator + /*! Returns the angle directly opposite of + the given angle, and will yield a result + between 0 and 2PI */ + angle + operator~()const + { + angle ret; + ret.v = v+PI; + return ret.mod(); + } +#endif // ETL_NOT_USED + +#ifdef ETL_WRAP_ANGLES + /*! Returns true if the shortest + angle from the left-hand to the + right-hand side is counter-clockwise */ + bool + operator<(const angle &rhs)const + { return dist(rhs).v<(value_type)0.0; } + + /*! Returns true if the shortest + angle from the left-hand to the + right-hand side is clockwise */ + bool + operator>(const angle &rhs)const + { return dist(rhs).v>(value_type)0.0; } + + /*! Returns true if the shortest + angle from the left-hand to the + right-hand side is counter-clockwise, + or if the angles are refer to the same + point on the unit circle. */ + bool + operator<=(const angle &rhs)const + { return dist(rhs).v<=(value_type)0.0; } + + /*! Returns true if the shortest + angle from the left-hand to the + right-hand side is clockwise, + or if the angles are refer to the same + point on the unit circle. */ + bool + operator>=(const angle &rhs)const + { 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 angle &rhs)const + { return std::abs(dist(rhs).v)ANGLE_EPSILON; } +#else // ETL_WRAP_ANGLES + /*! Returns true if the left-hand + side is less than the + right-hand side */ + bool + operator<(const angle &rhs)const + { return v < rhs.v; } + + /*! Returns true if the left-hand + side is greater than the + right-hand side */ + bool + operator>(const angle &rhs)const + { return v > rhs.v; } + + /*! Returns true if the left-hand + side is less or equal to the + right-hand side */ + bool + operator<=(const angle &rhs)const + { return v <= rhs.v; } + + /*! Returns true if the left-hand + side is greater than or equal + to the right-hand side */ + bool + operator>=(const angle &rhs)const + { return v >= rhs.v; } + + /*! Returns true if the angles + are the same, or close */ + bool + operator==(const angle &rhs)const + { return std::abs(v - rhs.v)ANGLE_EPSILON; } +#endif // ETL_WRAP_ANGLES + + //! Absolute Angle Function + /*! This function will return the + absolute value of the angle. */ + angle + abs()const + { + angle ret; + ret.v=std::abs(v); + return ret; + } + +#ifdef ETL_WRAP_ANGLES + //! Angle Difference Function + /*! This function will return the + shortest physical distance between + two angles, from -PI/2 to PI/2 + \sa angle operator-(const angle &) */ + angle + dist(const angle &rhs)const + { + angle ret; + ret.v=v-rhs.v; + ret.v-=rot_floor(ret.v+PI); + return ret; + } + + //! Rotation Modulus + /*! This function will return the + value of the angle between 0 and 2PI */ + angle + mod()const + { + angle ret(*this); + ret.v-=rot_floor(ret.v); + return ret; + } +#else // ETL_WRAP_ANGLES + //! Angle Difference Function + /*! This function will return the + difference between + two angles, just like + \sa angle operator-(const angle &) */ + angle + dist(const angle &rhs)const + { return angle(*this)-=rhs; } + + //! Rotation Modulus + /*! This function will return the + value of the angle */ + angle + mod()const + { + angle ret(*this); + return ret; + } +#endif // ETL_WRAP_ANGLES + + //! Zero Rotation (0 degrees) + static angle + zero() + { + angle ret; + ret.v=0; + return ret; + } + + //! One Complete Rotation (360 degrees) + static angle + one() + { + angle ret; + ret.v=PI*2; + return ret; + } + + //! One Half Rotation (180 degrees) + static angle + half() + { + angle ret; + ret.v=PI; + return ret; + } + + bool operator!()const { return std::abs(mod().v) < ANGLE_EPSILON; } + +private: + +#ifdef ETL_WRAP_ANGLES + static value_type rot_floor(value_type x) + { return static_cast(std::floor(x/(PI*2))*PI*2); } +#endif // ETL_WRAP_ANGLES + +public: + /* + ** Conversion Classes + */ + + class rad; + class deg; + class rot; + + /* + ** Trigonometric Classes + */ + + class sin; + class cos; + class tan; + + /* + ** Friend classes + */ + + friend class rad; + friend class deg; + friend class rot; + friend class sin; + friend class cos; + friend class tan; + + /* + ** Deprecated + */ + +#ifndef ETL_NO_DEPRECATED + typedef rad radians; + typedef deg degrees; + typedef rot rotations; +#endif +}; // END of class angle + +// ======================================================================== +/*! \class angle::rad _angle.h ETL/angle +** \brief Angle representation in radians +** \see angle +** \writeme +*/ +class angle::rad : public angle +{ +public: + explicit rad(const value_type &x) { v=x; } + rad(const angle &a):angle(a) { } + rad mod()const { return angle::mod(); } + rad dist(const angle &rhs)const { return angle::dist(rhs); } + value_type get()const { return v; } +#ifndef ETL_NO_DEPRECATED + // operator value_type()const ETL_DEPRECATED_FUNCTION; +#endif +}; // END of class angle::radians +// inline angle::rad::operator angle::value_type()const { return get(); } + +// ======================================================================== +/*! \class angle::deg _angle.h ETL/angle +** \brief Angle representation in degrees +** \see angle +** \writeme +*/ +class angle::deg : public angle +{ +public: + explicit deg(const value_type &x) { v=x*((PI*2)/360); } + deg(const angle &a):angle(a) { } + deg mod()const { return angle::mod(); } + deg dist(const angle &rhs)const { return angle::dist(rhs); } + value_type get()const { return v*360/(PI*2); } +#ifndef ETL_NO_DEPRECATED + // operator value_type()const ETL_DEPRECATED_FUNCTION; +#endif +}; // END of class angle::degrees +// inline angle::deg::operator angle::value_type()const { return get(); } + +// ======================================================================== +/*! \class angle::rot _angle.h ETL/angle +** \brief Angle representation in rotations +** \see angle +** \writeme +*/ +class angle::rot : public angle +{ +public: + explicit rot(const value_type &x) { v=x*(PI*2); } + rot(const angle &a):angle(a) { } + rot mod()const { return angle::mod(); } + rot dist(const angle &rhs)const { return angle::dist(rhs); } + value_type get()const { return v/(PI*2); } +#ifndef ETL_NO_DEPRECATED + // operator value_type()const ETL_DEPRECATED_FUNCTION; +#endif +}; // END of class angle::rotations +// inline angle::rot::operator angle::value_type()const { return get(); } + +// ======================================================================== +/*! \class angle::sin _angle.h ETL/angle +** \brief Angle representation as a sine function +** \see angle +** \writeme +*/ +class angle::sin : public angle +{ +public: + explicit sin(const value_type &x) { v=static_cast(std::asin(x)); } + sin(const angle &a):angle(a) { } + sin mod()const { return angle::mod(); } + sin dist(const angle &rhs)const { return angle::dist(rhs); } + value_type get()const { return static_cast(std::sin(v)); } +#ifndef ETL_NO_DEPRECATED + // operator value_type()const ETL_DEPRECATED_FUNCTION; +#endif +}; // END of class angle::sin +// inline angle::sin::operator angle::value_type()const { return get(); } + +// ======================================================================== +/*! \class angle::cos _angle.h ETL/angle +** \brief Angle representation as a cosine function +** \see angle +** \writeme +*/ +class angle::cos : public angle +{ +public: + explicit cos(const value_type &x) { v=(value_type)(std::acos(x)); } + cos(const angle &a):angle(a) { } + cos mod()const { return angle::mod(); } + cos dist(const angle &rhs)const { return angle::dist(rhs); } + value_type get()const { return (value_type)std::cos(v); } +#ifndef ETL_NO_DEPRECATED + // operator value_type()const ETL_DEPRECATED_FUNCTION; +#endif +}; // END of class angle::cos +// inline angle::cos::operator angle::value_type()const { return get(); } + +// ======================================================================== +/*! \class angle::tan _angle.h ETL/angle +** \brief Angle representation as a tangent function +** \see angle +** \writeme +*/ +class angle::tan : public angle +{ +public: + explicit tan(const value_type &x) { v=(value_type)(std::atan(x)); } + tan(const value_type &y,const value_type &x) { v=(value_type)(std::atan2(y,x)); } + tan(const angle &a):angle(a) { } + tan mod()const { return angle::mod(); } + tan dist(const angle &rhs)const { return angle::dist(rhs); } + value_type get()const { return (value_type)std::tan(v); } +#ifndef ETL_NO_DEPRECATED + // operator value_type()const ETL_DEPRECATED_FUNCTION; +#endif +}; // END of class angle::tan +// inline angle::tan::operator angle::value_type()const { return get(); } + +_ETL_END_NAMESPACE + +//#include + +template +struct affine_combo +{ + typedef T time_type; + + //affine_combo() { std::cerr<<"affine_combo: I was created!"<: I was DELETED!"< +struct distance_func : public std::binary_function +{ + etl::angle operator()(const etl::angle &a,const etl::angle &b)const + { + etl::angle delta=b.dist(a); + //if(delta