/************************************************************************* ** Pair.hpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** ** Copyright (C) 2005-2024 Martin Gieseking ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** ** published by the Free Software Foundation; either version 3 of ** ** the License, or (at your option) any later version. ** ** ** ** This program is distributed in the hope that it will be useful, but ** ** WITHOUT ANY WARRANTY; without even the implied warranty of ** ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** ** GNU General Public License for more details. ** ** ** ** You should have received a copy of the GNU General Public License ** ** along with this program; if not, see . ** *************************************************************************/ #ifndef PAIR_HPP #define PAIR_HPP #include #include #include #include "macros.hpp" template class Pair { public: explicit Pair (T x=0, T y=0) : _x(x), _y(y) {} template Pair (const Pair &p) : _x(U(p.x())), _y(U(p.y())) {} Pair (const Pair &p) =default; Pair (Pair &&p) =default; Pair& operator = (const Pair &p) =default; Pair& operator = (Pair &&p) =default; Pair operator += (const Pair &p) {_x += p._x; _y += p._y; return *this;} Pair operator -= (const Pair &p) {_x -= p._x; _y -= p._y; return *this;} Pair operator *= (T c) {_x *= c; _y *= c; return *this;} Pair operator /= (T c) {_x /= c; _y /= c; return *this;} Pair operator - () const {return Pair(-_x, -_y);} Pair ortho () const {return Pair(-_y, _x);} double length () const {return std::hypot(_x, _y);} bool operator == (const Pair &p) const {return _x == p._x && _y == p._y;} bool operator != (const Pair &p) const {return _x != p._x || _y != p._y;} T x () const {return _x;} T y () const {return _y;} void x (const T &xx) {_x = xx;} void y (const T &yy) {_y = yy;} std::ostream& write (std::ostream &os) const {return os << '(' << _x << ',' << _y << ')';} private: T _x, _y; }; template inline Pair abs (const Pair &p) { return Pair(std::abs(p.x()), std::abs(p.y())); } /** Returns the dot product of two 2D vectors. */ template inline T dot (const Pair &p1, const Pair &p2) { return p1.x()*p1.y() + p1.y()*p2.y(); } /** Returns the determinant of two 2D vectors. */ template inline T det (const Pair &p1, const Pair &p2) { return p1.x()*p2.y() - p1.y()*p2.x(); } struct Pair32 : public Pair { explicit Pair32 (int32_t x=0, int32_t y=0) : Pair(x, y) {} explicit Pair32 (double x, double y) : Pair(lround(x), lround(y)) {} explicit Pair32 (const Pair &p) : Pair32(p.x(), p.y()) {} Pair32 (const Pair &p) : Pair(p) {} }; typedef Pair DPair; inline DPair round (const DPair &p) { return DPair(std::lround(p.x()), std::lround(p.y())); } template<> template<> inline Pair::Pair (const Pair &p) : _x(int(round(p.x()))), _y(int(round(p.y()))) {} template IMPLEMENT_ARITHMETIC_OPERATOR(Pair, +) template IMPLEMENT_ARITHMETIC_OPERATOR(Pair, -) template IMPLEMENT_ARITHMETIC_OPERATOR2(Pair, T, *) template IMPLEMENT_ARITHMETIC_OPERATOR2(Pair, T, /) template IMPLEMENT_OUTPUT_OPERATOR(Pair) IMPLEMENT_ARITHMETIC_OPERATOR2(Pair32, int32_t, *) #endif