Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / ETL / tags / stable / ETL / _angle.h
index 1be01bb..c15f90d 100644 (file)
@@ -1,9 +1,11 @@
+#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
@@ -39,6 +41,8 @@
 # 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 ======================================= */
@@ -59,7 +63,7 @@ public:
 protected:
        typedef value_type unit;
 
-       unit v; //! Stored in rotations
+       unit v; //! Stored in radians; positive values indicate counter-clockwise.
 
 public:
 
@@ -69,41 +73,41 @@ public:
 
        const angle     &
        operator+=(const angle &rhs)
-               { v+=rhs.v; return *this; }
+       { v+=rhs.v; return *this; }
 
        const angle     &
        operator-=(const angle &rhs)
-               { v-=rhs.v; return *this; }
+       { v-=rhs.v; return *this; }
 
        const angle     &
        operator*=(const unit &rhs)
-               { v*=rhs; return *this; }
+       { v*=rhs; return *this; }
 
        const angle     &
        operator/=(const unit &rhs)
-               { v/=rhs; return *this; }
+       { v/=rhs; return *this; }
 
        //! Angle Addition Operator
        angle
        operator+(const angle &rhs)const
-               { return angle(*this)+=rhs; }
+       { return angle(*this)+=rhs; }
 
        //! Angle Subtraction Operator
        /*! \sa angle dist(const angle &) */
        angle
        operator-(const angle &rhs)const
-               { return angle(*this)-=rhs; }
+       { 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; }
+       { return angle(*this)*=rhs; }
 
        angle
        operator/(const unit &rhs)const
-               { return angle(*this)/=rhs; }
+       { return angle(*this)/=rhs; }
 
        //! Angle Negation
        angle
@@ -114,6 +118,7 @@ public:
                return ret;
        }
 
+#ifdef ETL_NOT_USED
        //! 180 degree rotation operator
        /*! Returns the angle directly opposite of
                the given angle, and will yield a result
@@ -122,62 +127,111 @@ public:
        operator~()const
        {
                angle ret;
-               ret.v=(value_type)std::floor(v+0.5f);
-               return ret;
+               ret.v = v+PI;
+               return ret.mod();
        }
+#endif // ETL_NOT_USED
 
+#ifdef ETL_WRAP_ANGLES
        /*! Returns true if the shortest
-               angle between the left-hand and
-               right-hand side is clockwise */
+               angle from the left-hand to the
+               right-hand side is counter-clockwise */
        bool
        operator<(const angle &rhs)const
-       { return v<rhs.v; }
-//     { return dist(rhs).v<(value_type)0.0; }
+       { return dist(rhs).v<(value_type)0.0; }
 
        /*! Returns true if the shortest
-               angle between the left-hand and
-               right-hand side is counter-clockwise */
+               angle from the left-hand to the
+               right-hand side is clockwise */
        bool
        operator>(const angle &rhs)const
-       { return v>rhs.v; }
-//     { return dist(rhs).v>(value_type)0.0; }
+       { return dist(rhs).v>(value_type)0.0; }
 
        /*! Returns true if the shortest
-               angle between the left-hand and
-               right-hand side is clockwise,
+               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 v<=rhs.v; }
-//     { return dist(rhs).v<=(value_type)0.0; }
+       { return dist(rhs).v<=(value_type)0.0; }
 
        /*! Returns true if the shortest
-               angle between the left-hand and
-               right-hand side is counter-clockwise,
+               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 v>=rhs.v; }
-//     { return dist(rhs).v>=(value_type)0.0; }
+       { 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 v==rhs.v; }
-//     { return dist(rhs).v==(value_type)0.0; }
+       { 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 v!=rhs.v; }
-//     { return dist(rhs).v!=(value_type)0.0; }
+       { 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
@@ -187,11 +241,8 @@ public:
        dist(const angle &rhs)const
        {
                angle ret;
-
                ret.v=v-rhs.v;
-
                ret.v-=rot_floor(ret.v+PI);
-
                return ret;
        }
 
@@ -205,7 +256,28 @@ public:
                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()
        {
@@ -214,32 +286,36 @@ public:
                return ret;
        }
 
+       //! One Complete Rotation (360 degrees)
        static angle
        one()
        {
                angle ret;
-               ret.v=PI;
+               ret.v=PI*2;
                return ret;
        }
 
+       //! One Half Rotation (180 degrees)
        static angle
        half()
        {
                angle ret;
-               ret.v=PI*0.5;
+               ret.v=PI;
                return ret;
        }
 
-       bool operator!()const { return v==0; }
+       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:
        /*
-       ** Converstion Classes
+       ** Conversion Classes
        */
 
        class rad;
@@ -247,7 +323,7 @@ public:
        class rot;
 
        /*
-       ** Trigometric Classes
+       ** Trigonometric Classes
        */
 
        class sin;
@@ -289,12 +365,12 @@ public:
        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;
+       // operator value_type()const ETL_DEPRECATED_FUNCTION;
 #endif
-       value_type get()const { return v; }
 }; // END of class angle::radians
-inline angle::rad::operator angle::value_type()const { return get(); }
+// inline angle::rad::operator angle::value_type()const { return get(); }
 
 // ========================================================================
 /*!    \class  angle::deg      _angle.h        ETL/angle
@@ -311,10 +387,10 @@ public:
        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;
+       // operator value_type()const ETL_DEPRECATED_FUNCTION;
 #endif
 }; // END of class angle::degrees
-inline angle::deg::operator angle::value_type()const { return get(); }
+// inline angle::deg::operator angle::value_type()const { return get(); }
 
 // ========================================================================
 /*!    \class  angle::rot      _angle.h        ETL/angle
@@ -331,10 +407,10 @@ public:
        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;
+       // operator value_type()const ETL_DEPRECATED_FUNCTION;
 #endif
 }; // END of class angle::rotations
-inline angle::rot::operator angle::value_type()const { return get(); }
+// inline angle::rot::operator angle::value_type()const { return get(); }
 
 // ========================================================================
 /*!    \class  angle::sin      _angle.h        ETL/angle
@@ -351,10 +427,10 @@ public:
        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;
+       // operator value_type()const ETL_DEPRECATED_FUNCTION;
 #endif
 }; // END of class angle::sin
-inline angle::sin::operator angle::value_type()const { return get(); }
+// inline angle::sin::operator angle::value_type()const { return get(); }
 
 // ========================================================================
 /*!    \class  angle::cos      _angle.h        ETL/angle
@@ -369,12 +445,12 @@ public:
        cos(const angle &a):angle(a) { }
        cos     mod()const { return angle::mod(); }
        cos dist(const angle &rhs)const { return angle::dist(rhs); }
-       operator value_type()const ETL_DEPRECATED_FUNCTION;
-#ifndef ETL_NO_DEPRECATED
        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(); }
+// inline angle::cos::operator angle::value_type()const { return get(); }
 
 // ========================================================================
 /*!    \class  angle::tan      _angle.h        ETL/angle
@@ -390,12 +466,12 @@ public:
        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;
+       // operator value_type()const ETL_DEPRECATED_FUNCTION;
 #endif
-       value_type get()const { return (value_type)std::tan(v); }
 }; // END of class angle::tan
-inline angle::tan::operator angle::value_type()const { return get(); }
+// inline angle::tan::operator angle::value_type()const { return get(); }
 
 _ETL_END_NAMESPACE
 
@@ -435,7 +511,6 @@ struct distance_func<etl::angle> : public std::binary_function<etl::angle, etl::
        etl::angle uncook(const etl::angle &x)const { return x; }
 };
 
-
 /* === E N D =============================================================== */
 
 #endif