#ifndef __JMATRIX2D__ #define __JMATRIX2D__ #include #include "JIO/JSerialisable.hh" namespace JGEOMETRY2D { namespace { using JIO::JReader; using JIO::JWriter; } /** * Data structure for an arbitrary 2x2 matrix. */ class JMatrix2D { public: /** * Default constructor (= identity matrix). */ JMatrix2D() { a00_ = 1; a01_ = 0; a10_ = 0; a11_ = 1; } double a00() const { return a00_; } double a01() const { return a01_; } double a10() const { return a10_; } double a11() const { return a11_; } /** * Transpose. */ JMatrix2D& transpose() { std::swap(a10_,a01_); return *this; } /** * Check whether this is the identity matrix. * * \param eps precision */ bool isIdentity(const double eps = 1.0e-10) const { return (fabs(1.0 - a00()) <= eps && fabs(1.0 - a11()) <= eps && fabs(a01()) <= eps && fabs(a10()) <= eps); } /** * Matrix multiplication. * * \param B JMatrix3D * \return this matrix */ JMatrix2D& multiply(const JMatrix2D& B) { const double c00 = a00() * B.a00() + a01() * B.a10(); const double c01 = a00() * B.a01() + a01() * B.a11(); const double c10 = a10() * B.a00() + a11() * B.a10(); const double c11 = a10() * B.a01() + a11() * B.a11(); a00_ = c00; a01_ = c01; a10_ = c10; a11_ = c11; return *this; } /** * Transform. * * \param __x x value * \param __y y value */ void transform(double& __x, double& __y) const { const double x = a00() * __x + a01() * __y; const double y = a10() * __x + a11() * __y; __x = x; __y = y; } /** * Read JMatrix2D from input. * * \param in JReader * \param matrix JMatrix2D * \return JReader */ friend inline JReader& operator>>(JReader& in, JMatrix2D& matrix) { in >> matrix.a00_; in >> matrix.a01_; in >> matrix.a10_; in >> matrix.a11_; return in; } /** * Write JMatrix2D to output. * * \param out JWriter * \param matrix JMatrix2D * \return JWriter */ friend inline JWriter& operator<<(JWriter& out, const JMatrix2D& matrix) { out << matrix.a00_; out << matrix.a01_; out << matrix.a10_; out << matrix.a11_; return out; } protected: double a00_, a01_; double a10_, a11_; }; } #endif