#ifndef __JAXIS2D__ #define __JAXIS2D__ #include #include #include "JIO/JSerialisable.hh" #include "JGeometry2D/JPosition2D.hh" #include "JGeometry2D/JDirection2D.hh" #include "JGeometry2D/JRotation2D.hh" #include "JGeometry2D/JSegment2D.hh" /** * \author mdejong */ namespace JGEOMETRY2D {} namespace JPP { using namespace JGEOMETRY2D; } namespace JGEOMETRY2D { using JIO::JReader; using JIO::JWriter; /** * Axis object. * * An axis object consists of a position and a direction. */ class JAxis2D : public JPosition2D, public JDirection2D { public: /** * Default constructor. */ JAxis2D() : JPosition2D (), JDirection2D() {} /** * Constructor. * * \param pos position */ JAxis2D(const JVector2D& pos) : JPosition2D (pos), JDirection2D() {} /** * Constructor. * * \param pos position * \param dir direction */ JAxis2D(const JVector2D& pos, const JVersor2D& dir) : JPosition2D (pos), JDirection2D(dir) {} /** * Constructor. * * \param segment line segment */ JAxis2D(const JSegment2D& segment) : JPosition2D (segment.first), JDirection2D(segment.second - segment.first) {} /** * Get axis. * * \return axis */ const JAxis2D& getAxis() const { return *this; } /** * Set axis. * * \param axis axis */ void setAxis(const JAxis2D& axis) { *this = axis; } /** * Negate axis. * * \return this axis */ JAxis2D& negate() { static_cast (*this).negate(); static_cast(*this).negate(); return *this; } /** * Move vertex along this axis. * * \param step step */ void move(const double step) { getPosition() += step * JVector2D(getDirection()); } /** * Test whether this axis and given line segment intersect. * * \param segment line segment * \return true if axis and line segment intersect; else false */ bool intersects(const JSegment2D& segment) const { if (getCCW(segment.first, this->getPosition(), segment.second)) return (this->getDirection().getPerpDot(segment.first - this->getPosition()) > 0.0 && this->getDirection().getPerpDot(segment.second - this->getPosition()) < 0.0); else return (this->getDirection().getPerpDot(segment.first - this->getPosition()) < 0.0 && this->getDirection().getPerpDot(segment.second - this->getPosition()) > 0.0); } /** * Get intersection of two axes. * * \param axis axis * \param precision precision * \return longitudinal position */ double getIntersection(const JAxis2D& axis, const double precision = 1.0e-8) const { const double gp = this->getDirection().getPerpDot(axis.getDirection()); if (fabs(gp) > precision) return axis.getDirection().getPerpDot(this->getPosition() - axis.getPosition()) / gp; else return this->getDistance(axis.getPosition()); } /** * Get squared of distance to point. * * \param point point * \return square of distance */ double getDistanceSquared(const JVector2D& point) const { JVector2D D(this->getDirection()); const JVector2D U(point - this->getPosition()); const double u = D.getDot(U); D.mul(u); D.sub(U); return D.getLengthSquared(); } /** * Get distance to point. * * \param point point * \return distance */ double getDistance(const JVector2D& point) const { return sqrt(getDistanceSquared(point)); } /** * Rotate axis. * * \param R rotation matrix * \return this axis */ JAxis2D& rotate(const JRotation2D& R) { static_cast (*this).rotate(R); static_cast(*this).rotate(R); return *this; } /** * Rotate back axis. * * \param R rotation matrix * \return this axis */ JAxis2D& rotate_back(const JRotation2D& R) { static_cast (*this).rotate_back(R); static_cast(*this).rotate_back(R); return *this; } /** * Read axis from input. * * \param in input stream * \param axis axis * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JAxis2D& axis) { in >> static_cast (axis); in >> static_cast(axis); return in; } /** * Write axis to output. * * \param out output stream * \param axis axis * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JAxis2D& axis) { out << static_cast (axis); out << ' '; out << static_cast(axis); return out; } /** * Read axis from input. * * \param in reader * \param axis axis * \return reader */ friend inline JReader& operator>>(JReader& in, JAxis2D& axis) { in >> static_cast (axis); in >> static_cast(axis); return in; } /** * Write axis to output. * * \param out writer * \param axis axis * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JAxis2D& axis) { out << static_cast (axis); out << static_cast(axis); return out; } }; } #endif