#ifndef __JVERSOR3Z__ #define __JVERSOR3Z__ #include #include #include #include #include "JIO/JSerialisable.hh" #include "JLang/JManip.hh" #include "JMath/JMath.hh" #include "JGeometry2D/JVersor2D.hh" #include "JGeometry3D/JAngle3D.hh" #include "JGeometry3D/JVector3D.hh" #include "JGeometry3D/JVersor3D.hh" /** * \author mdejong */ namespace JGEOMETRY3D {} namespace JPP { using namespace JGEOMETRY3D; } namespace JGEOMETRY3D { using JMATH::JMath; using JIO::JReader; using JIO::JWriter; using JGEOMETRY2D::JVersor2D; /** * Data structure for normalised vector in positive z-direction. * The member methods getDX() and getDY() refer to the corresponding direction cosines. * Note that the direction cosines may have any value. * The method getDZ() will simply return 0 if the sum of the squares of the direction cosines is larger than 1. */ class JVersor3Z : public JMath { public: /** * Default constructor. */ JVersor3Z() : __dx(0.0), __dy(0.0) {} /** * Constructor. * * \param dir direction cosines */ JVersor3Z(const JVersor2D& dir) : __dx(dir.getDX()), __dy(dir.getDY()) {} /** * Constructor. * * \param dx direction cosine dx/dz * \param dy direction cosine dy/dz */ JVersor3Z(const double dx, const double dy) : __dx(dx), __dy(dy) {} /** * Get direction. * * \return direction */ const JVersor3Z& getDirection() const { return static_cast(*this); } /** * Get direction. * * \return direction */ JVersor3Z& getDirection() { return static_cast(*this); } /** * Set direction. * * \param direction direction */ void setDirection(const JVersor3Z& direction) { static_cast(*this) = direction; } /** * Get angle. * * \return angle */ operator JAngle3D() const { return JAngle3D(getDX(), getDY(), getDZ()); } /** * Type conversion operator. * * \return position */ operator JVector3D() const { return JVector3D(getDX(), getDY(), getDZ()); } /** * Type conversion operator. * * \return direction */ operator JVersor3D() const { return JVersor3D(getDX(), getDY(), getDZ()); } /** * Get x direction. * * \return x direction */ double getDX() const { return __dx; } /** * Get y direction. * * \return y direction */ double getDY() const { return __dy; } /** * Get z direction. * * \return z direction */ double getDZ() const { const double v = getDX()*getDX() + getDY()*getDY(); if (v <= 1.0) return sqrt(1.0 - v); else return 0.0; } /** * Prefix unary minus. * * \return this versor */ JVersor3Z& negate() { __dx = -__dx; __dy = -__dy; return *this; } /** * Addition operator. * * \param value versor * \return this versor */ JVersor3Z& add(const JVersor3Z& value) { __dx += value.getDX(); __dy += value.getDY(); return *this; } /** * Subtraction operator. * * \param value versor * \return this versor */ JVersor3Z& sub(const JVersor3Z& value) { __dx -= value.getDX(); __dy -= value.getDY(); return *this; } /** * Multiplication operator. * * \param value multiplication factor * \return this versor */ JVersor3Z& mul(const double value) { __dx *= value; __dy *= value; return *this; } /** * Division operator. * * \param value multiplication factor * \return this versor */ JVersor3Z& div(const double value) { __dx /= value; __dy /= value; return *this; } /** * Check equality. * * \param versor versor * \param precision precision * \return true if versors are equal; else false */ bool equals(const JVersor3D& versor, const double precision = std::numeric_limits::min()) const { return (fabs(getDX() - versor.getDX()) <= precision && fabs(getDY() - versor.getDY()) <= precision); } /** * Get dot product. * * \param dir direction * \return dot product */ double getDot(const JVersor3Z& dir) const { return getDX() * dir.getDX() + getDY() * dir.getDY() + getDZ() * dir.getDZ(); } /** * Get dot product. * * \param angle angle * \return dot product */ double getDot(const JAngle3D& angle) const { return getDX() * angle.getDX() + getDY() * angle.getDY() + getDZ() * angle.getDZ(); } /** * Get dot product. * * \param pos position * \return dot product */ double getDot(const JVector3D& pos) const { return getDX() * pos.getX() + getDY() * pos.getY() + getDZ() * pos.getZ(); } /** * Get dot product. * * \param dir direction * \return dot product */ double getDot(const JVersor3D& dir) const { return getDX() * dir.getDX() + getDY() * dir.getDY() + getDZ() * dir.getDZ(); } /** * Read versor from input. * * \param in input stream * \param versor versor * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JVersor3Z& versor) { return in >> versor.__dx >> versor.__dy; } /** * Write versor to output. * * \param out output stream * \param versor versor * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JVersor3Z& versor) { const JFormat format(out, getFormat(JFormat_t(9, 6, std::ios::fixed | std::ios::showpos))); return out << format << versor.getDX() << ' ' << format << versor.getDY(); } /** * Read versor from input. * * \param in reader * \param versor versor * \return reader */ friend inline JReader& operator>>(JReader& in, JVersor3Z& versor) { return in >> versor.__dx >> versor.__dy; } /** * Write versor to output. * * \param out writer * \param versor versor * \return writer */ friend inline JWriter& operator<<(JWriter& out, const JVersor3Z& versor) { return out << versor.__dx << versor.__dy; } protected: double __dx; double __dy; }; } #endif