#ifndef __JVERSOR2D__ #define __JVERSOR2D__ #include #include "JIO/JSerialisable.hh" #include "JGeometry2D/JDirection2D.hh" #include "JGeometry2D/JRotation2D.hh" namespace JGEOMETRY2D { namespace { using JIO::JReader; using JIO::JWriter; } /** * Data structure for normalised vector in two dimensions. */ class JVersor2D { public: /** * Default constructor. */ JVersor2D() : __dx(0.0), __dy(0.0) {} /** * Constructor. * * \param angle angle */ JVersor2D(const JAngle2D& angle) : __dx(angle.getDX()), __dy(angle.getDY()) {} /** * Constructor. * * \param dx dx value * \param dy dy value */ JVersor2D(const double dx, const double dy) : __dx(dx), __dy(dy) { normalise(); } /** * Get direction. * * \return direction */ const JVersor2D& getDirection() const { return static_cast(*this); } /** * Get direction. * * \return direction */ JVersor2D& getDirection() { return static_cast(*this); } /** * Set direction. * * \param dir direction */ void setDirection(const JVersor2D& dir) { static_cast(*this) = dir; } /** * Read JVersor2D from input. * * \param in JReader * \param versor JVersor2D * \return JReader */ friend inline JReader& operator>>(JReader& in, JVersor2D& versor) { JAngle2D angle; in >> angle; __dx = angle.getDX(); __dy = angle.getDY(); return in; } /** * Write JVersor2D to output. * * \param out JWriter * \param versor JVersor2D * \return JWriter */ friend inline JWriter& operator<<(JWriter& out, const JVersor2D& versor) { const JDirection2D angle(getDX(), getDY()); out << static_cast(angle); return out; } /** * Type conversion operator. * * \return JAngle2D */ operator JDirection2D() const { return JDirection2D(getDX(), getDY()); } /** * Get x direction. * * \return x direction */ double getDX() const { return __dx; } /** * Get y direction. * * \return y direction */ double getDY() const { return __dy; } /** * Rotate. * * \param R rotation matrix */ JVersor2D& rotate(const JRotation2D& R) { R.rotate(__dx, __dy); return *this; } /** * Rotate back. * * \param R rotation matrix */ JVersor2D& rotate_back(const JRotation2D& R) { R.rotate_back(__dx, __dy); return *this; } /** * Get dot product. * * \param versor JVersor2D * \return dot product */ double getDot(const JVersor2D& versor) const { return getDX() * versor.getDX() + getDY() * versor.getDY(); } /** * Normalise versor. */ void normalise() { const double v = sqrt(getDX()*getDX() + getDY()*getDY()); if (v != 0.0) { __dx /= v; __dy /= v; } } protected: double __dx; double __dy; }; /** * Dot product. * * \param first JVersor2D * \param second JVersor2D * \return dot product */ inline double dot(const JVersor2D& first, const JVersor2D& second) { return first.getDot(second); } } #endif