X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgeometry%2Fangle.h;fp=source%2Fgeometry%2Fangle.h;h=edd752122f3436055028f6dab93332f3836a0f96;hb=6ff13022b53830d35283905d562c2ef3af198cc1;hp=0000000000000000000000000000000000000000;hpb=ec9e0699ef686a3314d4c9ee0f39b29a92d3aeed;p=libs%2Fmath.git diff --git a/source/geometry/angle.h b/source/geometry/angle.h new file mode 100644 index 0000000..edd7521 --- /dev/null +++ b/source/geometry/angle.h @@ -0,0 +1,221 @@ +#ifndef MSP_GEOMETRY_ANGLE_H_ +#define MSP_GEOMETRY_ANGLE_H_ + +#include + +namespace Msp { +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. +*/ +template +class Angle +{ +private: + T value; + + explicit Angle(T); +public: + template + Angle(const Angle &); + + static Angle from_degrees(T); + static Angle from_radians(T); + + static Angle right(); + static Angle quarter_circle(); + static Angle straight(); + static Angle half_circle(); + static Angle full_circle(); + + T degrees() const; + T radians() const; + + Angle &operator+=(const Angle &); + Angle &operator-=(const Angle &); + Angle &operator*=(T); + Angle &operator/=(T); +}; + +template +inline Angle::Angle(T v): + value(v) +{ } + +template +template +inline Angle::Angle(const Angle &other): + value(other.value) +{ } + +template +inline Angle Angle::from_degrees(T d) +{ + return Angle(d*M_PI/180); +} + +template +inline Angle Angle::from_radians(T r) +{ + return Angle(r); +} + +template +inline Angle Angle::right() +{ + 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; +} + +template +inline Angle &Angle::operator+=(const Angle &a) +{ + value += a.value; + return *this; +} + +template +inline Angle operator+(const Angle &a1, const Angle &a2) +{ + Angle r(a1); + return r += a2; +} + +template +inline Angle &Angle::operator-=(const Angle &a) +{ + value -= a.value; + return *this; +} + +template +inline Angle operator-(const Angle &a1, const Angle &a2) +{ + Angle r(a1); + return r -= a2; +} + +template +inline Angle &Angle::operator*=(T s) +{ + value *= s; + return *this; +} + +template +inline Angle operator*(const Angle &a, T s) +{ + Angle r(a); + return r *= s; +} + +template +inline Angle operator*(T s, const Angle &a) +{ + return a*s; +} + +template +inline Angle &Angle::operator/=(T s) +{ + value /= s; + return *this; +} + +template +inline Angle operator/(const Angle &a, T s) +{ + Angle r(a); + return r /= s; +} + +template +inline Angle operator/(T s, const Angle &a) +{ + return a/s; +} + +template +inline T sin(const Angle &angle) +{ + return std::sin(angle.radians()); +} + +template +inline Angle asin(T s) +{ + return Angle::from_radians(std::asin(s)); +} + +template +inline T cos(const Angle &angle) +{ + return std::cos(angle.radians()); +} + +template +inline Angle acos(T s) +{ + return Angle::from_radians(std::acos(s)); +} + +template +inline T tan(const Angle &angle) +{ + return std::tan(angle.radians()); +} + +template +inline Angle atan(T s) +{ + return Angle::from_radians(std::atan(s)); +} + +template +inline Angle atan2(T y, T x) +{ + return Angle::from_radians(std::atan2(y, x)); +} + +} // namespace Geometry +} // namespace Msp + +#endif