Files
pip/libs/main/math/pipoint.h
peri4 cf25cacc17 decompose pip_cmg
add serialization/pijsonserialization.h for JSON de/serialization
add -J flag for pip_cmg to make JSON serialization methods
not finished yet, but basically workable now
2025-08-02 18:48:38 +03:00

191 lines
7.2 KiB
C++
Raw Permalink 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 Two-dimensional point class
//! \~russian Класс двумерной точки
/*
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"
//! \brief
//! \~english Two-dimensional point class
//! \~russian Класс двумерной точки
//! \details
//! Данный класс позволяет хранить и работать с двумерными точками.
//! Для работы с объектами реализованы операторы сложения, вычитания и проверки на ревенство и неравенство.
//! Также доступны методы для перемещения точек \a translate(), \a translated(), \a move(), \a moved()
//! и перевода из декартовой системы координат в полярную \a toPolar() и обратно \a fromPolar().
template<typename Type>
class PIP_EXPORT PIPoint {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
Type x;
Type y;
//! \~russian Создает новую точку.
PIPoint() { x = y = Type(); }
//! \~russian Создает новую точку с заданными координатами.
PIPoint(Type x_, Type y_) { set(x_, y_); }
//! \~russian Задать новые координаты точке.
PIPoint<Type> & set(Type x_, Type y_) {
x = x_;
y = y_;
return *this;
}
//! \~russian Задать новые координаты точке.
PIPoint<Type> & set(const PIPoint<Type> & p) {
x = p.x;
y = p.y;
return *this;
}
//! \~russian Переместить точку.
PIPoint<Type> & translate(Type x_, Type y_) {
x += x_;
y += y_;
return *this;
}
//! \~russian Переместить точку.
PIPoint<Type> & translate(const PIPoint<Type> & p) {
x += p.x;
y += p.y;
return *this;
}
//! \~russian Создать копию точки и переместить её.
PIPoint<Type> translated(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//! \~russian Создать копию точки и переместить её.
PIPoint<Type> translated(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//! \~russian Переместить точку.
//! \details Является копией метода \a translate().
PIPoint<Type> & move(Type x_, Type y_) { return translate(x_, y_); }
//! \~russian Переместить точку.
//! \details Является копией метода \a translate().
PIPoint<Type> & move(const PIPoint<Type> & p) { return translate(p); }
//! \~russian Создать копию точки и переместить её.
//! \details Является копией метода \a translated().
PIPoint<Type> moved(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//! \~russian Создать копию точки и переместить её.
//! \details Является копией метода \a translated().
PIPoint<Type> moved(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//! \~russian Посчитать угол(радианы) в поолярной системе координат.
double angleRad() const { return atan2(y, x); }
//! \~russian Посчитать угол(градусы) в поолярной системе координат.
double angleDeg() const { return toDeg(atan2(y, x)); }
//! \~russian Перевести копию точки в полярную систему координат.
PIPoint<Type> toPolar(bool isDeg = false) const { return PIPoint<Type>(sqrt(x * x + y * y), isDeg ? angleDeg() : angleRad()); }
//! \~russian Перевести копию точки из полярной системы координат в декартовую.
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) { return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x)); }
//! \~russian
//! Прибавить координаты второй точки и сохранить.
//! \details Является копией метода \a translate().
PIPoint<Type> & operator+=(const PIPoint<Type> & p) {
translate(p);
return *this;
}
PIPoint<Type> & operator*=(Type v) {
x *= v;
y *= v;
return *this;
}
PIPoint<Type> & operator/=(Type v) {
x /= v;
y /= v;
return *this;
}
//! \~russian Сложить координаты двух точек.
PIPoint<Type> operator+(const PIPoint<Type> & p) { return PIPoint<Type>(x + p.x, y + p.y); }
//! \~russian Прибавить к координатам одинаковое значение.
PIPoint<Type> operator+(const Type & p) { return PIPoint<Type>(x + p, y + p); }
//! \~russian Вычесть из координат координаты второй точки - найти смещение.
PIPoint<Type> operator-(const PIPoint<Type> & p) { return PIPoint<Type>(x - p.x, y - p.y); }
//! \~russian Вычесть из координат одинаковое значение.
PIPoint<Type> operator-(const Type & p) { return PIPoint<Type>(x - p, y - p); }
//! \~russian Инвертировать координаты точки.
PIPoint<Type> operator-() { return PIPoint<Type>(-x, -y); }
//! \~russian Умножить координаты точки.
PIPoint<Type> operator*(Type v) { return PIPoint<Type>(x * v, y * v); }
//! \~russian Делить координаты точки.
PIPoint<Type> operator/(Type v) { return PIPoint<Type>(x / v, y / v); }
//! \~russian Проверить равенство координат двух точек.
bool operator==(const PIPoint<Type> & p) const { return (x == p.x && y == p.y); }
//! \~russian Проверить неравенство координат двух точек.
bool operator!=(const PIPoint<Type> & p) const { return (x != p.x || y != p.y); }
};
//! \~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;
}
typedef PIPoint<int> PIPointi;
typedef PIPoint<uint> PIPointu;
typedef PIPoint<float> PIPointf;
typedef PIPoint<double> PIPointd;
#endif // PIPOINT_H