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

214 lines
7.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 piline.h
//! \~\ingroup Math
//! \~\brief
//! \~english Two-dimensional line segment type
//! \~russian Тип двумерного отрезка
/*
PIP - Platform Independent Primitives
Two-dimensional line 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 PILINE_H
#define PILINE_H
#include "pipoint.h"
//! \~\ingroup Math
//! \~\brief
//! \~english Two-dimensional line segment.
//! \~russian Двумерный отрезок.
//! \~\details
//! \~english Stores start and end points of a segment on a plane.
//! \~russian Хранит начальную и конечную точки отрезка на плоскости.
template<typename Type>
class PIP_EXPORT PILine {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
//! \~english Segment start point.
//! \~russian Начальная точка отрезка.
PIPoint<Type> p0;
//! \~english Segment end point.
//! \~russian Конечная точка отрезка.
PIPoint<Type> p1;
//! \~english Constructs empty segment.
//! \~russian Создает пустой отрезок.
PILine() {}
//! \~english Constructs segment from two points.
//! \~russian Создает отрезок по двум точкам.
PILine(const PIPoint<Type> & p0_, const PIPoint<Type> & p1_) {
p0 = p0_;
p1 = p1_;
}
//! \~english Constructs segment from endpoint coordinates.
//! \~russian Создает отрезок по координатам концов.
PILine(Type x0, Type y0, Type x1, Type y1) {
p0.set(x0, y0);
p1.set(x1, y1);
}
//! \~english Sets segment endpoints from two points.
//! \~russian Задает концы отрезка по двум точкам.
PILine<Type> & set(const PIPoint<Type> & p0_, const PIPoint<Type> & p1_) {
p0 = p0_;
p1 = p1_;
return *this;
}
//! \~english Sets segment endpoints from coordinates.
//! \~russian Задает концы отрезка по координатам.
PILine<Type> & set(Type x0, Type y0, Type x1, Type y1) {
p0.set(x0, y0);
p1.set(x1, y1);
return *this;
}
//! \~english Returns `true` if segment endpoints are equal.
//! \~russian Возвращает `true`, если концы отрезка совпадают.
bool isEmpty() const { return (p0 == p1); }
//! \~english Returns horizontal span between endpoints.
//! \~russian Возвращает горизонтальный размах между концами.
Type width() const { return piAbs<Type>(p1.x - p0.x); }
//! \~english Returns vertical span between endpoints.
//! \~russian Возвращает вертикальный размах между концами.
Type height() const { return piAbs<Type>(p1.y - p0.y); }
//! \~english Shifts the segment by `x` and `y`.
//! \~russian Сдвигает отрезок на `x` и `y`.
PILine<Type> & translate(Type x, Type y) {
p0.translate(x, y);
p1.translate(x, y);
return *this;
}
//! \~english Shifts the segment by a point offset.
//! \~russian Сдвигает отрезок на смещение, заданное точкой.
PILine<Type> & translate(const PIPoint<Type> & p) {
p0.translate(p);
p1.translate(p);
return *this;
}
//! \~english Returns translated copy of the segment.
//! \~russian Возвращает смещенную копию отрезка.
PILine<Type> translated(Type x, Type y) const {
PILine<Type> l(*this);
l.translate(x, y);
return l;
}
//! \~english Returns copy shifted by a point offset.
//! \~russian Возвращает копию, смещенную на точку.
PILine<Type> translated(const PIPoint<Type> & p) const {
PILine<Type> l(*this);
l.translate(p);
return l;
}
//! \~english Same as \a translate().
//! \~russian Синоним \a translate().
PILine<Type> & move(Type x, Type y) { return translate(x, y); }
//! \~english Same as \a translate().
//! \~russian Синоним \a translate().
PILine<Type> & move(const PIPoint<Type> & p) { return translate(p); }
//! \~english Same as \a translated().
//! \~russian Синоним \a translated().
PILine<Type> moved(Type x, Type y) const {
PILine<Type> l(*this);
l.translate(x, y);
return l;
}
//! \~english Same as \a translated().
//! \~russian Синоним \a translated().
PILine<Type> moved(const PIPoint<Type> & p) const {
PILine<Type> l(*this);
l.translate(p);
return l;
}
//! \~english Shifts both coordinates by `x`.
//! \~russian Сдвигает обе координаты на `x`.
void operator+=(Type x) { translate(x, x); }
//! \~english Shifts the segment by a point offset.
//! \~russian Сдвигает отрезок на смещение, заданное точкой.
void operator+=(const PIPoint<Type> & p) { translate(p); }
//! \~english Shifts both coordinates by `-x`.
//! \~russian Сдвигает обе координаты на `-x`.
void operator-=(Type x) { translate(-x, -x); }
//! \~english Shifts the segment by the negated point offset.
//! \~russian Сдвигает отрезок на отрицательное смещение точки.
void operator-=(const PIPoint<Type> & p) { translate(-p); }
//! \~english Returns segment shifted by a point offset.
//! \~russian Возвращает отрезок, смещенный на точку.
PILine<Type> operator+(const PIPoint<Type> & p) { return translated(p); }
//! \~english Returns segment shifted by the negated point offset.
//! \~russian Возвращает отрезок, смещенный на отрицательное смещение точки.
PILine<Type> operator-(const PIPoint<Type> & p) { return translated(-p); }
//! \~english Checks whether segment endpoints are equal.
//! \~russian Проверяет равенство концов отрезков.
bool operator==(const PILine<Type> & r) const { return (p0 == r.p0 && p1 == r.p1); }
//! \~english Checks whether segments differ.
//! \~russian Проверяет различие отрезков.
bool operator!=(const PILine<Type> & r) const { return (p1 != r.p1 || p1 != r.p1); }
};
//! \relatesalso PICout
//! \~english Writes segment coordinates to \a PICout.
//! \~russian Выводит координаты отрезка в \a PICout.
template<typename Type>
PICout operator<<(PICout & s, const PILine<Type> & v) {
s.space();
s.saveAndSetControls(0);
s << "Line{" << v.p0 << ", " << v.p1 << "}";
s.restoreControls();
return s;
}
//! \~english Alias for segment with `int` coordinates.
//! \~russian Псевдоним отрезка с координатами типа `int`.
typedef PILine<int> PILinei;
//! \~english Alias for segment with `uint` coordinates.
//! \~russian Псевдоним отрезка с координатами типа `uint`.
typedef PILine<uint> PILineu;
//! \~english Alias for segment with `float` coordinates.
//! \~russian Псевдоним отрезка с координатами типа `float`.
typedef PILine<float> PILinef;
//! \~english Alias for segment with `double` coordinates.
//! \~russian Псевдоним отрезка с координатами типа `double`.
typedef PILine<double> PILined;
#endif // PILINE_H