+#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
# 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 ======================================= */
protected:
typedef value_type unit;
- unit v; //! Stored in rotations
+ unit v; //! Stored in radians; positive values indicate counter-clockwise.
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
return ret;
}
+#ifdef ETL_NOT_USED
//! 180 degree rotation operator
/*! Returns the angle directly opposite of
the given angle, and will yield a result
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
dist(const angle &rhs)const
{
angle ret;
-
ret.v=v-rhs.v;
-
ret.v-=rot_floor(ret.v+PI);
-
return ret;
}
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()
{
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;
class rot;
/*
- ** Trigometric Classes
+ ** Trigonometric Classes
*/
class sin;
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
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
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
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
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
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
etl::angle uncook(const etl::angle &x)const { return x; }
};
-
/* === E N D =============================================================== */
#endif