X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgeometry%2Fangle.h;h=207a5a273721a3475e6302abeffa6995f336dbf7;hb=93e7cf250208c36befb4b1a7337f5302c0e1da54;hp=edd752122f3436055028f6dab93332f3836a0f96;hpb=6ff13022b53830d35283905d562c2ef3af198cc1;p=libs%2Fmath.git diff --git a/source/geometry/angle.h b/source/geometry/angle.h index edd7521..207a5a2 100644 --- a/source/geometry/angle.h +++ b/source/geometry/angle.h @@ -8,8 +8,7 @@ namespace Geometry { /** A planar angle. Creating an Angle from a raw value or extracting it requires -specifying whether degrees or radians are used. This eliminates a common -source of errors. +specifying the units used. This eliminates a common source of errors. */ template class Angle @@ -17,39 +16,43 @@ class Angle private: T value; - explicit Angle(T); + explicit Angle(T v): value(v) { } public: + Angle(): value(0) { } template - Angle(const Angle &); + Angle(const Angle &other): value(other.radians()) { } static Angle from_degrees(T); static Angle from_radians(T); + static Angle from_turns(T); - static Angle right(); - static Angle quarter_circle(); - static Angle straight(); - static Angle half_circle(); - static Angle full_circle(); + static Angle zero() { return from_radians(0); } + static Angle right() { return from_radians(M_PI/2); } + static Angle quarter_turn() { return right(); } + static Angle straight() { return from_radians(M_PI); } + static Angle half_turn() { return straight(); } + static Angle full_turn() { return from_radians(2*M_PI); } - T degrees() const; - T radians() const; + T degrees() const { return value*180/M_PI; } + T radians() const { return value; } + T turns() const { return value/(2*M_PI); } Angle &operator+=(const Angle &); Angle &operator-=(const Angle &); Angle &operator*=(T); Angle &operator/=(T); -}; -template -inline Angle::Angle(T v): - value(v) -{ } + bool operator==(const Angle &other) const { return value==other.value; } + bool operator!=(const Angle &other) const { return value!=other.value; } + bool operator<(const Angle &other) const { return value(const Angle &other) const { return value>other.value; } + bool operator>=(const Angle &other) const { return value>=other.value; } -template -template -inline Angle::Angle(const Angle &other): - value(other.value) -{ } + Angle &wrap_with_base(const Angle &); + Angle &wrap_positive(); + Angle &wrap_balanced(); +}; template inline Angle Angle::from_degrees(T d) @@ -64,45 +67,9 @@ inline Angle Angle::from_radians(T r) } template -inline Angle Angle::right() +inline Angle Angle::from_turns(T t) { - return from_radians(M_PI/2); -} - -template -inline Angle Angle::quarter_circle() -{ - return right(); -} - -template -inline Angle Angle::straight() -{ - return from_radians(M_PI); -} - -template -inline Angle Angle::half_circle() -{ - return straight(); -} - -template -inline Angle Angle::full_circle() -{ - return from_radians(M_PI*2); -} - -template -inline T Angle::degrees() const -{ - return value*180/M_PI; -} - -template -inline T Angle::radians() const -{ - return value; + return Angle(t*2*M_PI); } template @@ -133,6 +100,12 @@ inline Angle operator-(const Angle &a1, const Angle &a2) return r -= a2; } +template +inline Angle operator-(const Angle &a) +{ + return Angle::zero()-a; +} + template inline Angle &Angle::operator*=(T s) { @@ -173,46 +146,109 @@ inline Angle operator/(T s, const Angle &a) return a/s; } +template +inline T operator/(const Angle &a1, const Angle &a2) +{ + return a1.radians()/a2.radians(); +} + +template +inline Angle &Angle::wrap_with_base(const Angle &b) +{ + while(value=b.value+2*M_PI) + value -= 2*M_PI; + return *this; +} + +template +inline Angle &Angle::wrap_positive() +{ + return wrap_with_base(zero()); +} + +template +inline Angle &Angle::wrap_balanced() +{ + return wrap_with_base(-half_turn()); +} + +template +inline Angle wrap_with_base(const Angle &a, const Angle &b) +{ + Angle r = a; + return r.wrap_with_base(b); +} + +template +inline Angle wrap_positive(const Angle &a) +{ + Angle r = a; + return r.wrap_positive(); +} + +template +inline Angle wrap_balanced(const Angle &a) +{ + Angle r = a; + return r.wrap_balanced(); +} + +template +inline Angle abs(const Angle &angle) +{ + using std::abs; + return Angle::from_radians(abs(angle.radians())); +} + template inline T sin(const Angle &angle) { - return std::sin(angle.radians()); + using std::sin; + return sin(angle.radians()); } template inline Angle asin(T s) { - return Angle::from_radians(std::asin(s)); + using std::asin; + return Angle::from_radians(asin(s)); } template inline T cos(const Angle &angle) { - return std::cos(angle.radians()); + using std::cos; + return cos(angle.radians()); } template inline Angle acos(T s) { - return Angle::from_radians(std::acos(s)); + using std::acos; + return Angle::from_radians(acos(s)); } template inline T tan(const Angle &angle) { - return std::tan(angle.radians()); + using std::tan; + return tan(angle.radians()); } template inline Angle atan(T s) { - return Angle::from_radians(std::atan(s)); + using std::atan; + return Angle::from_radians(atan(s)); } template inline Angle atan2(T y, T x) { - return Angle::from_radians(std::atan2(y, x)); + using std::atan2; + return Angle::from_radians(atan2(y, x)); } } // namespace Geometry