#ifndef __JANGLE2D__ #define __JANGLE2D__ #include #include #include #include #include "JIO/JSerialisable.hh" #include "JLang/JManip.hh" #include "JMath/JMath.hh" #include "JMath/JConstants.hh" /** * \author mdejong */ namespace JGEOMETRY2D {} namespace JPP { using namespace JGEOMETRY2D; } namespace JGEOMETRY2D { using JIO::JReader; using JIO::JWriter; using JMATH::JMath; /** * Data structure for angle in two dimensions. * This class serves as input to the rotation matrix JRotation2D. */ class JAngle2D : public JMath { public: /** * Default constructor. */ JAngle2D() : __phi(0.0) {} /** * Constructor. * * \param phi phi angle [rad] */ JAngle2D(const double phi) : __phi(phi) {} /** * Constructor. * * \param x x value * \param y y value */ JAngle2D(const double x, const double y) : __phi(atan2(y,x)) {} /** * Get phi angle. * * \return phi angle */ double getPhi() const { return __phi; } /** * Get x direction. * * \return x direction */ double getDX() const { return cos(__phi); } /** * Get y direction. * * \return y direction */ double getDY() const { return sin(__phi); } /** * Negate angle. * * \return this angle */ JAngle2D& negate() { __phi = -__phi; return *this; } /** * Add angle. * * \param angle angle * \return this angle */ JAngle2D& add(const JAngle2D& angle) { __phi += angle.getPhi(); return *this; } /** * Subtract angle. * * \param angle angle * \return this angle */ JAngle2D& sub(const JAngle2D& angle) { __phi -= angle.getPhi(); return *this; } /** * Scale angle. * * \param factor multiplication factor * \return this angle */ JAngle2D& mul(const double factor) { __phi *= factor; return *this; } /** * Scale angle. * * \param factor division factor * \return this angle */ JAngle2D& div(const double factor) { __phi /= factor; return *this; } /** * Check equality. * * \param angle angle * \param precision precision * \return true if angles are equal; else false */ bool equals(const JAngle2D& angle, const double precision = std::numeric_limits::min()) const { return fabs(getPhi() - angle.getPhi()) <= precision; } /** * Get dot product. * * \param angle angle * \return dot product */ double getDot(const JAngle2D& angle) const { return cos(getPhi() - angle.getPhi()); } /** * Normalise angle. * - phi angle will be between 0 and 2π * * \return this angle */ JAngle2D& normalise() { using JMATH::PI; if (__phi > 2*PI) { do { __phi -= 2*PI; } while (__phi > 2*PI); } if (__phi < 0.0) { do { __phi += 2*PI; } while (__phi < 0.0); } return *this; } /** * Read angle from input. * * \param in input stream * \param angle angle * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JAngle2D& angle) { return in >> angle.__phi; } /** * Write angle to output. * * \param out output stream * \param angle angle * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JAngle2D& angle) { const JFormat format(out, getFormat(JFormat_t(9, 5, std::ios::fixed | std::ios::showpos))); return out << format << angle.getPhi(); } /** * Read angle from input. * * \param in reader * \param angle angle * \return reader */ friend inline JReader& operator>>(JReader& in, JAngle2D& angle) { return in >> angle.__phi; } /** * Write angle to output. * * \param out writer * \param angle angle * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JAngle2D& angle) { return out << angle.__phi; } protected: double __phi; }; } #endif