Files
pip/libs/main/math/pipoint.h
2026-03-12 14:46:57 +03:00

233 lines
8.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \~\file pipoint.h
//! \~\ingroup Math
//! \~\brief
//! \~english The PIPoint class provides a two-dimensional point on the plane.
//! \~russian Класс PIPoint представляет точку на плоскости с двумя координатами.
/*
PIP - Platform Independent Primitives
Two-dimensional point class
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIPOINT_H
#define PIPOINT_H
#include "pimathbase.h"
//! \~\ingroup Math
//! \~\brief
//! \~english Two-dimensional point.
//! \~russian Двумерная точка.
//! \~\details
//! \~english Stores point coordinates and provides basic translation and conversion helpers.
//! \~russian Хранит координаты точки и предоставляет базовые методы смещения и преобразования.
template<typename Type>
class PIP_EXPORT PIPoint {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
//! \~english Horizontal coordinate.
//! \~russian Горизонтальная координата.
Type x;
//! \~english Vertical coordinate.
//! \~russian Вертикальная координата.
Type y;
//! \~english Constructs point at the origin.
//! \~russian Создает точку в начале координат.
PIPoint() { x = y = Type(); }
//! \~english Constructs point from coordinates.
//! \~russian Создает точку с заданными координатами.
PIPoint(Type x_, Type y_) { set(x_, y_); }
//! \~english Sets point coordinates.
//! \~russian Задает координаты точки.
PIPoint<Type> & set(Type x_, Type y_) {
x = x_;
y = y_;
return *this;
}
//! \~english Copies coordinates from another point.
//! \~russian Копирует координаты из другой точки.
PIPoint<Type> & set(const PIPoint<Type> & p) {
x = p.x;
y = p.y;
return *this;
}
//! \~english Shifts the point by `x_` and `y_`.
//! \~russian Сдвигает точку на `x_` и `y_`.
PIPoint<Type> & translate(Type x_, Type y_) {
x += x_;
y += y_;
return *this;
}
//! \~english Shifts the point by another point.
//! \~russian Сдвигает точку на координаты другой точки.
PIPoint<Type> & translate(const PIPoint<Type> & p) {
x += p.x;
y += p.y;
return *this;
}
//! \~english Returns translated copy of the point.
//! \~russian Возвращает смещенную копию точки.
PIPoint<Type> translated(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//! \~english Returns copy shifted by another point.
//! \~russian Возвращает копию, смещенную на другую точку.
PIPoint<Type> translated(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//! \~english Same as \a translate().
//! \~russian Синоним \a translate().
PIPoint<Type> & move(Type x_, Type y_) { return translate(x_, y_); }
//! \~english Same as \a translate().
//! \~russian Синоним \a translate().
PIPoint<Type> & move(const PIPoint<Type> & p) { return translate(p); }
//! \~english Same as \a translated().
//! \~russian Синоним \a translated().
PIPoint<Type> moved(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//! \~english Same as \a translated().
//! \~russian Синоним \a translated().
PIPoint<Type> moved(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//! \~english Returns polar angle in radians.
//! \~russian Возвращает полярный угол в радианах.
double angleRad() const { return atan2(y, x); }
//! \~english Returns polar angle in degrees.
//! \~russian Возвращает полярный угол в градусах.
double angleDeg() const { return toDeg(atan2(y, x)); }
//! \~english Returns polar form with radius in \a x and angle in \a y.
//! \~russian Возвращает полярную форму, где радиус хранится в \a x, а угол в \a y.
PIPoint<Type> toPolar(bool isDeg = false) const { return PIPoint<Type>(sqrt(x * x + y * y), isDeg ? angleDeg() : angleRad()); }
//! \~english Builds Cartesian point from polar pair with angle in \a x and radius in \a y.
//! \~russian Строит декартову точку из полярной пары, где угол хранится в \a x, а радиус в \a y.
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) { return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x)); }
//! \~english Same as \a translate().
//! \~russian Синоним \a translate().
PIPoint<Type> & operator+=(const PIPoint<Type> & p) {
translate(p);
return *this;
}
//! \~english Multiplies both coordinates by `v`.
//! \~russian Умножает обе координаты на `v`.
PIPoint<Type> & operator*=(Type v) {
x *= v;
y *= v;
return *this;
}
//! \~english Divides both coordinates by `v`.
//! \~russian Делит обе координаты на `v`.
PIPoint<Type> & operator/=(Type v) {
x /= v;
y /= v;
return *this;
}
//! \~english Returns sum of two points.
//! \~russian Возвращает сумму двух точек.
PIPoint<Type> operator+(const PIPoint<Type> & p) { return PIPoint<Type>(x + p.x, y + p.y); }
//! \~english Returns point with `p` added to both coordinates.
//! \~russian Возвращает точку с добавлением `p` к обеим координатам.
PIPoint<Type> operator+(const Type & p) { return PIPoint<Type>(x + p, y + p); }
//! \~english Returns difference between two points.
//! \~russian Возвращает разность двух точек.
PIPoint<Type> operator-(const PIPoint<Type> & p) { return PIPoint<Type>(x - p.x, y - p.y); }
//! \~english Returns point with `p` subtracted from both coordinates.
//! \~russian Возвращает точку с вычитанием `p` из обеих координат.
PIPoint<Type> operator-(const Type & p) { return PIPoint<Type>(x - p, y - p); }
//! \~english Returns point with inverted coordinates.
//! \~russian Возвращает точку с инвертированными координатами.
PIPoint<Type> operator-() { return PIPoint<Type>(-x, -y); }
//! \~english Returns point scaled by `v`.
//! \~russian Возвращает точку, масштабированную на `v`.
PIPoint<Type> operator*(Type v) { return PIPoint<Type>(x * v, y * v); }
//! \~english Returns point divided by `v`.
//! \~russian Возвращает точку, деленную на `v`.
PIPoint<Type> operator/(Type v) { return PIPoint<Type>(x / v, y / v); }
//! \~english Checks whether point coordinates are equal.
//! \~russian Проверяет равенство координат точек.
bool operator==(const PIPoint<Type> & p) const { return (x == p.x && y == p.y); }
//! \~english Checks whether point coordinates differ.
//! \~russian Проверяет неравенство координат точек.
bool operator!=(const PIPoint<Type> & p) const { return (x != p.x || y != p.y); }
};
//! \relatesalso PICout
//! \~english Writes point coordinates to \a PICout.
//! \~russian Выводит координаты точки в \a PICout.
template<typename Type>
PICout operator<<(PICout & s, const PIPoint<Type> & v) {
s.space();
s.saveAndSetControls(0);
s << "Point{" << v.x << ", " << v.y << "}";
s.restoreControls();
return s;
}
//! \~english Alias for point with `int` coordinates.
//! \~russian Псевдоним точки с координатами типа `int`.
typedef PIPoint<int> PIPointi;
//! \~english Alias for point with `uint` coordinates.
//! \~russian Псевдоним точки с координатами типа `uint`.
typedef PIPoint<uint> PIPointu;
//! \~english Alias for point with `float` coordinates.
//! \~russian Псевдоним точки с координатами типа `float`.
typedef PIPoint<float> PIPointf;
//! \~english Alias for point with `double` coordinates.
//! \~russian Псевдоним точки с координатами типа `double`.
typedef PIPoint<double> PIPointd;
#endif // PIPOINT_H