Files
pip/libs/main/math/pipoint.h

220 lines
8.8 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 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;
//! \~english Creates a new point.
//! \~russian Создает новую точку.
PIPoint() { x = y = Type(); }
//! \~english Creates a new point with given coordinates.
//! \~russian Создает новую точку с заданными координатами.
PIPoint(Type x_, Type y_) { set(x_, y_); }
//! \~english Set new coordinates for the point.
//! \~russian Задать новые координаты точке.
PIPoint<Type> & set(Type x_, Type y_) {
x = x_;
y = y_;
return *this;
}
//! \~english Set new coordinates from another point.
//! \~russian Задать новые координаты точке.
PIPoint<Type> & set(const PIPoint<Type> & p) {
x = p.x;
y = p.y;
return *this;
}
//! \~english Translate the point by x and y.
//! \~russian Переместить точку.
PIPoint<Type> & translate(Type x_, Type y_) {
x += x_;
y += y_;
return *this;
}
//! \~english Translate the point by another point.
//! \~russian Переместить точку.
PIPoint<Type> & translate(const PIPoint<Type> & p) {
x += p.x;
y += p.y;
return *this;
}
//! \~english Create a copy of the point and translate it.
//! \~russian Создать копию точки и переместить её.
PIPoint<Type> translated(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//! \~english Create a copy of the point and translate it by another point.
//! \~russian Создать копию точки и переместить её.
PIPoint<Type> translated(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//! \~english Translate the point. Alias for \a translate().
//! \~russian Переместить точку.
//! \details Является копией метода \a translate().
PIPoint<Type> & move(Type x_, Type y_) { return translate(x_, y_); }
//! \~english Translate the point by another point. Alias for \a translate().
//! \~russian Переместить точку.
//! \details Является копией метода \a translate().
PIPoint<Type> & move(const PIPoint<Type> & p) { return translate(p); }
//! \~english Create a copy of the point and translate it. Alias for \a translated().
//! \~russian Создать копию точки и переместить её.
//! \details Является копией метода \a translated().
PIPoint<Type> moved(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//! \~english Create a copy of the point and translate it by another point. Alias for \a translated().
//! \~russian Создать копию точки и переместить её.
//! \details Является копией метода \a translated().
PIPoint<Type> moved(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//! \~english Calculate angle in radians in polar coordinate system.
//! \~russian Посчитать угол(радианы) в поолярной системе координат.
double angleRad() const { return atan2(y, x); }
//! \~english Calculate angle in degrees in polar coordinate system.
//! \~russian Посчитать угол(градусы) в поолярной системе координат.
double angleDeg() const { return toDeg(atan2(y, x)); }
//! \~english Convert copy of point to polar coordinate system.
//! \~russian Перевести копию точки в полярную систему координат.
PIPoint<Type> toPolar(bool isDeg = false) const { return PIPoint<Type>(sqrt(x * x + y * y), isDeg ? angleDeg() : angleRad()); }
//! \~english Convert point from polar to cartesian coordinate system.
//! \~russian Перевести копию точки из полярной системы координат в декартовую.
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) { return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x)); }
//! \~english Add second point coordinates and save.
//! \~russian Прибавить координаты второй точки и сохранить.
//! \details Является копией метода \a translate().
PIPoint<Type> & operator+=(const PIPoint<Type> & p) {
translate(p);
return *this;
}
//! \~english Multiply coordinates by value.
PIPoint<Type> & operator*=(Type v) {
x *= v;
y *= v;
return *this;
}
//! \~english Divide coordinates by value.
PIPoint<Type> & operator/=(Type v) {
x /= v;
y /= v;
return *this;
}
//! \~english Add coordinates of two points.
//! \~russian Сложить координаты двух точек.
PIPoint<Type> operator+(const PIPoint<Type> & p) { return PIPoint<Type>(x + p.x, y + p.y); }
//! \~english Add value to both coordinates.
//! \~russian Прибавить к координатам одинаковое значение.
PIPoint<Type> operator+(const Type & p) { return PIPoint<Type>(x + p, y + p); }
//! \~english Subtract second point coordinates - get offset.
//! \~russian Вычесть из координат координаты второй точки - найти смещение.
PIPoint<Type> operator-(const PIPoint<Type> & p) { return PIPoint<Type>(x - p.x, y - p.y); }
//! \~english Subtract value from both coordinates.
//! \~russian Вычесть из координат одинаковое значение.
PIPoint<Type> operator-(const Type & p) { return PIPoint<Type>(x - p, y - p); }
//! \~english Invert point coordinates.
//! \~russian Инвертировать координаты точки.
PIPoint<Type> operator-() { return PIPoint<Type>(-x, -y); }
//! \~english Multiply point coordinates.
//! \~russian Умножить координаты точки.
PIPoint<Type> operator*(Type v) { return PIPoint<Type>(x * v, y * v); }
//! \~english Divide point coordinates.
//! \~russian Делить координаты точки.
PIPoint<Type> operator/(Type v) { return PIPoint<Type>(x / v, y / v); }
//! \~english Check equality of two points.
//! \~russian Проверить равенство координат двух точек.
bool operator==(const PIPoint<Type> & p) const { return (x == p.x && y == p.y); }
//! \~english Check inequality of two points.
//! \~russian Проверить неравенство координат двух точек.
bool operator!=(const PIPoint<Type> & p) const { return (x != p.x || y != p.y); }
};
//! \~english Stream output operator for PIPoint.
//! \~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