--- /dev/null
+#include <stdio.h>
+/* ========================================================================
+** 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 <cmath>
+#include <functional>
+
+/* === 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; }
+
+ /*! Returns false 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; }
+
+ /*! Returns false if the angles
+ are different */
+ 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<value_type>(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<value_type>(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<value_type>(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 <iostream>
+
+template <typename T>
+struct affine_combo<etl::angle, T>
+{
+ typedef T time_type;
+
+ //affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was created!"<<std::endl; }
+ //~affine_combo() { std::cerr<<"affine_combo<etl::angle,float>: I was DELETED!"<<std::endl; }
+
+ etl::angle operator()(const etl::angle &a,const etl::angle &b,const time_type &t)const
+ {
+ return b.dist(a)*(float)t+a;
+ }
+
+ etl::angle reverse(const etl::angle &x, const etl::angle &b, const time_type &t)const
+ {
+ return x.dist(b*(float)t)*(float)(time_type(1)/(time_type(1)-t));
+ }
+};
+
+template <>
+struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::angle, etl::angle>
+{
+ etl::angle operator()(const etl::angle &a,const etl::angle &b)const
+ {
+ etl::angle delta=b.dist(a);
+ //if(delta<etl::angle::zero())
+ // return delta+etl::angle::one();
+ return delta;
+ }
+
+ etl::angle cook(const etl::angle &x)const { return x; }
+ etl::angle uncook(const etl::angle &x)const { return x; }
+};
+
+/* === E N D =============================================================== */
+
+#endif