geometry_refact #86

Merged
andrey merged 4 commits from geometry_refact into master 2022-03-21 14:14:12 +03:00
10 changed files with 772 additions and 136 deletions

View File

@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip) project(pip)
set(pip_MAJOR 2) set(pip_MAJOR 2)
set(pip_MINOR 33) set(pip_MINOR 34)
set(pip_REVISION 1) set(pip_REVISION 0)
set(pip_SUFFIX ) set(pip_SUFFIX )
set(pip_COMPANY SHS) set(pip_COMPANY SHS)
set(pip_DOMAIN org.SHS) set(pip_DOMAIN org.SHS)

BIN
doc/images/pirect.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -619,6 +619,16 @@ PIRectd PIVariant::toRect() const {
} }
/** @brief Returns variant content as rect
* \details In case of PILined type returns line value. \n
* In case of other types returns empty PILined. */
PILined PIVariant::toLine() const {
PIByteArray ba(_content);
if (_type == PIVariant::pivLine) {PILined r; ba >> r; return r;}
return PILined();
}
/** @brief Returns variant content as math vector /** @brief Returns variant content as math vector
* \details In case of PIMathVectord type returns rect value. \n * \details In case of PIMathVectord type returns rect value. \n
* In case of other types returns empty PIMathVectord. */ * In case of other types returns empty PIMathVectord. */

View File

@@ -234,11 +234,12 @@ public:
pivFile /** PIVariantTypes::File */ , pivFile /** PIVariantTypes::File */ ,
pivDir /** PIVariantTypes::Dir */ , pivDir /** PIVariantTypes::Dir */ ,
pivColor /** PIVariantTypes::Color */ , pivColor /** PIVariantTypes::Color */ ,
pivPoint /** PIPoint */ , pivPoint /** PIPoint<double> */ ,
pivRect /** PIRect */ , pivRect /** PIRect<double> */ ,
pivIODevice /** PIVariantTypes::IODevice */ , pivIODevice /** PIVariantTypes::IODevice */ ,
pivMathVector /** PIMathVectord */ , pivMathVector /** PIMathVector<double> */ ,
pivMathMatrix /** PIMathMatrixd */ , pivMathMatrix /** PIMathMatrix<double> */ ,
pivLine /** PILine<double> */ ,
pivCustom /** Custom */ = 0xFF pivCustom /** Custom */ = 0xFF
}; };
@@ -333,6 +334,9 @@ public:
//! Constructs variant from rect //! Constructs variant from rect
PIVariant(const PIRectd & v) {initType(v);} PIVariant(const PIRectd & v) {initType(v);}
//! Constructs variant from line
PIVariant(const PILined & v) {initType(v);}
//! Constructs variant from MathVector //! Constructs variant from MathVector
PIVariant(const PIMathVectord & v) {initType(v);} PIVariant(const PIMathVectord & v) {initType(v);}
@@ -424,6 +428,9 @@ public:
//! Set variant content and type to rect //! Set variant content and type to rect
void setValue(const PIRectd & v) {initType(v);} void setValue(const PIRectd & v) {initType(v);}
//! Set variant content and type to line
void setValue(const PILined & v) {initType(v);}
//! Set variant content and type to math vector //! Set variant content and type to math vector
void setValue(const PIMathVectord & v) {initType(v);} void setValue(const PIMathVectord & v) {initType(v);}
@@ -456,6 +463,7 @@ public:
PIVariantTypes::IODevice toIODevice() const; PIVariantTypes::IODevice toIODevice() const;
PIPointd toPoint() const; PIPointd toPoint() const;
PIRectd toRect() const; PIRectd toRect() const;
PILined toLine() const;
PIMathVectord toMathVector() const; PIMathVectord toMathVector() const;
PIMathMatrixd toMathMatrix() const; PIMathMatrixd toMathMatrix() const;
@@ -527,6 +535,8 @@ public:
//! Assign operator //! Assign operator
PIVariant & operator =(const PIRectd & v) {setValue(v); return *this;} PIVariant & operator =(const PIRectd & v) {setValue(v); return *this;}
//! Assign operator //! Assign operator
PIVariant & operator =(const PILined & v) {setValue(v); return *this;}
//! Assign operator
PIVariant & operator =(const PIMathVectord & v) {setValue(v); return *this;} PIVariant & operator =(const PIMathVectord & v) {setValue(v); return *this;}
//! Assign operator //! Assign operator
PIVariant & operator =(const PIMathMatrixd & v) {setValue(v); return *this;} PIVariant & operator =(const PIMathMatrixd & v) {setValue(v); return *this;}
@@ -661,6 +671,7 @@ template<> inline PIVariantTypes::Color PIVariant::value() const {return toColor
template<> inline PIVariantTypes::IODevice PIVariant::value() const {return toIODevice();} template<> inline PIVariantTypes::IODevice PIVariant::value() const {return toIODevice();}
template<> inline PIPointd PIVariant::value() const {return toPoint();} template<> inline PIPointd PIVariant::value() const {return toPoint();}
template<> inline PIRectd PIVariant::value() const {return toRect();} template<> inline PIRectd PIVariant::value() const {return toRect();}
template<> inline PILined PIVariant::value() const {return toLine();}
template<> inline PIVariant PIVariant::value() const {return *this;} template<> inline PIVariant PIVariant::value() const {return *this;}
template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);}
@@ -690,6 +701,7 @@ template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::Color & v
template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::IODevice & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariantTypes::IODevice & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIPointd & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIRectd & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PILined & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIMathVectord & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIMathMatrixd & v) {return PIVariant(v);}
template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PIVariant & v) {return PIVariant(v);}
@@ -721,6 +733,7 @@ template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::Color>() {r
template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::IODevice>() {return PIVariant::pivIODevice;} template<> inline PIVariant::Type PIVariant::getType<PIVariantTypes::IODevice>() {return PIVariant::pivIODevice;}
template<> inline PIVariant::Type PIVariant::getType<PIPointd>() {return PIVariant::pivPoint;} template<> inline PIVariant::Type PIVariant::getType<PIPointd>() {return PIVariant::pivPoint;}
template<> inline PIVariant::Type PIVariant::getType<PIRectd>() {return PIVariant::pivRect;} template<> inline PIVariant::Type PIVariant::getType<PIRectd>() {return PIVariant::pivRect;}
template<> inline PIVariant::Type PIVariant::getType<PILined>() {return PIVariant::pivLine;}
template<> inline PIVariant::Type PIVariant::getType<PIMathVectord>() {return PIVariant::pivMathVector;} template<> inline PIVariant::Type PIVariant::getType<PIMathVectord>() {return PIVariant::pivMathVector;}
template<> inline PIVariant::Type PIVariant::getType<PIMathMatrixd>() {return PIVariant::pivMathMatrix;} template<> inline PIVariant::Type PIVariant::getType<PIMathMatrixd>() {return PIVariant::pivMathMatrix;}
@@ -751,6 +764,7 @@ REGISTER_NS_VARIANT(PIVariantTypes, Color)
REGISTER_NS_VARIANT(PIVariantTypes, IODevice) REGISTER_NS_VARIANT(PIVariantTypes, IODevice)
REGISTER_VARIANT(PIPointd) REGISTER_VARIANT(PIPointd)
REGISTER_VARIANT(PIRectd) REGISTER_VARIANT(PIRectd)
REGISTER_VARIANT(PILined)
REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathVectord)
REGISTER_VARIANT(PIMathMatrixd) REGISTER_VARIANT(PIMathMatrixd)

View File

@@ -1,10 +1,25 @@
/*! @file pigeometry.h /*! \file pigeometry.h
* @brief Geometry base class * \ingroup Math
* \brief
* \~english Geometry base classes
* \~russian Базовые геометрические классы
* \~\details
* \~english
* Add \a PIPoint, \a PILine and \a PIRect classes.
* \~russian
* Содержит классы: \a PIPoint, \a PILine и \a PIRect.
* * \~\authors
* \~english
* Ivan Pelipenko peri4ko@yandex.ru;
* Andrey Bychkov work.a.b@yandex.ru;
* \~russian
* Иван Пелипенко peri4ko@yandex.ru;
* Андрей Бычков work.a.b@yandex.ru;
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Geometry Geometry base classes
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -19,130 +34,11 @@
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PIGEOMETRY_H #ifndef PIGEOMETRY_H
#define PIGEOMETRY_H #define PIGEOMETRY_H
#include "pimathbase.h" #include "pipoint.h"
#include "piline.h"
template<typename Type> #include "pirect.h"
class PIP_EXPORT PIPoint {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
Type x;
Type y;
PIPoint() {x = y = Type();}
PIPoint(Type x_, Type y_) {set(x_, y_);}
PIPoint<Type> & set(Type x_, Type y_) {x = x_; y = y_; return *this;}
PIPoint<Type> & move(Type x_, Type y_) {x += x_; y += y_; return *this;}
PIPoint<Type> & move(const PIPoint<Type> & p) {x += p.x; y += p.y; return *this;}
double angleRad() const {return atan2(y, x);}
int angleDeg() const {return round(atan2(y, x) * rad2deg);}
PIPoint<Type> toPolar(bool isDeg = false) const {return PIPoint<Type>(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());}
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) {return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x));}
PIPoint<Type> operator +(const PIPoint<Type> & p) {return PIPoint<Type>(x + p.x, y + p.y);}
PIPoint<Type> operator +(const Type & p) {return PIPoint<Type>(x + p, y + p);}
PIPoint<Type> operator -(const PIPoint<Type> & p) {return PIPoint<Type>(x - p.x, y - p.y);}
PIPoint<Type> operator -(const Type & p) {return PIPoint<Type>(x - p, y - p);}
PIPoint<Type> operator -() {return PIPoint<Type>(-x, -y);}
PIPoint<Type> operator *(const Type & d) {return PIPoint<Type>(x * d, y * d);}
PIPoint<Type> operator /(const Type & d) {return PIPoint<Type>(x / d, y / d);}
bool operator ==(const PIPoint<Type> & p) const {return (x == p.x && y == p.y);}
bool operator !=(const PIPoint<Type> & p) const {return (x != p.x || y != p.y);}
};
template<typename Type>
PICout operator <<(PICout & s, const PIPoint<Type> & v) {s.setControl(0, true); s << "Point{" << v.x << ", " << v.y << "}"; s.restoreControl(); return s;}
typedef PIPoint<int> PIPointi;
typedef PIPoint<uint> PIPointu;
typedef PIPoint<float> PIPointf;
typedef PIPoint<double> PIPointd;
template<typename Type>
class PIP_EXPORT PIRect {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
Type x0;
Type y0;
Type x1;
Type y1;
PIRect() {x0 = y0 = x1 = y1 = Type();}
PIRect(Type x, Type y, Type w, Type h) {set(x, y, w, h);}
PIRect(const PIPoint<Type> & tl, const PIPoint<Type> & br) {set(tl.x, tl.y, br.x, br.y);}
PIRect(const PIPoint<Type> & p0, const PIPoint<Type> & p1, const PIPoint<Type> & p2) {set(piMin<Type>(p0.x, p1.x, p2.x), piMin<Type>(p0.y, p1.y, p2.y),
piMax<Type>(p0.x, p1.x, p2.x), piMax<Type>(p0.y, p1.y, p2.y));}
PIRect<Type> & set(Type x, Type y, Type w, Type h) {x0 = x; y0 = y; x1 = x + w; y1 = y + h; return *this;}
bool pointIn(Type x, Type y) const {return (x <= x1 && x >= x0 && y <= y1 && y >= y0);}
bool pointIn(const PIPoint<Type> & p) const {return pointIn(p.x, p.y);}
bool isEmpty() const {return (x1 - x0 == 0 && y1 - y0 == 0);}
PIRect<Type> & translate(Type x, Type y) {x0 += x; x1 += x; y0 += y; y1 += y; return *this;}
PIRect<Type> & translate(const PIPoint<Type> & p) {x0 += p.x; x1 += p.x; y0 += p.y; y1 += p.y; return *this;}
PIRect<Type> translated(Type x, Type y) {PIRect<Type> r(*this); r.translate(x, y); return r;}
PIRect<Type> translated(const PIPoint<Type> & p) {PIRect<Type> r(*this); r.translate(p); return r;}
PIRect<Type> & scale(Type x, Type y) {setWidth(width() * x); setHeight(height() * y); return *this;}
PIRect<Type> & scale(const PIPoint<Type> & p) {setWidth(width() * p.x); setHeight(height() * p.y); return *this;}
PIRect<Type> scaled(Type x, Type y) {PIRect<Type> r(*this); r.scale(x, y); return r;}
PIRect<Type> scaled(const PIPoint<Type> & p) {PIRect<Type> r(*this); r.scale(p); return r;}
PIRect<Type> & normalize() {if (x0 > x1) piSwap<Type>(x0, x1); if (y0 > y1) piSwap<Type>(y0, y1); return *this;}
PIRect<Type> normalized() {PIRect<Type> r(*this); r.normalize(); return r;}
PIRect<Type> & unite(const PIRect<Type> & r) {x0 = piMin<Type>(x0, r.x0); y0 = piMin<Type>(y0, r.y0); x1 = piMax<Type>(x1, r.x1); y1 = piMax<Type>(y1, r.y1); return *this;}
PIRect<Type> united(const PIRect<Type> & rect) {PIRect<Type> r(*this); r.unite(rect); return r;}
PIRect<Type> & intersect(const PIRect<Type> & r) {x0 = piMax<Type>(x0, r.x0); y0 = piMax<Type>(y0, r.y0); x1 = piMin<Type>(x1, r.x1); y1 = piMin<Type>(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;}
PIRect<Type> intersected(const PIRect<Type> & rect) {PIRect<Type> r(*this); r.intersect(rect); return r;}
Type top() const {return y0;}
Type left() const {return x0;}
Type right() const {return x1;}
Type bottom() const {return y1;}
Type width() const {return x1 - x0;}
Type height() const {return y1 - y0;}
PIPoint<Type> topLeft() {return PIPoint<Type>(x0, y0);}
PIPoint<Type> topRigth() {return PIPoint<Type>(x1, y0);}
PIPoint<Type> bottomLeft() {return PIPoint<Type>(x0, y1);}
PIPoint<Type> bottomRight() {return PIPoint<Type>(x1, y1);}
void setTop(Type v) {y0 = v;}
void setLeft(Type v) {x0 = v;}
void setRigth(Type v) {x1 = v;}
void setBottom(Type v) {y1 = v;}
void setWidth(Type v) {x1 = x0 + v;}
void setHeight(Type v) {y1 = y0 + v;}
PIRect<Type> operator -() {return PIRect<Type>(-x0, -y0, -width(), -height());}
void operator +=(Type x) {translate(x, x);}
void operator +=(const PIPoint<Type> & p) {translate(p);}
void operator -=(Type x) {translate(-x, -x);}
void operator -=(const PIPoint<Type> & p) {translate(-p);}
void operator *=(Type p) {x0 *= p; x1 *= p; y0 *= p; y1 *= p;}
void operator /=(Type p) {x0 /= p; x1 /= p; y0 /= p; y1 /= p;}
void operator |=(const PIRect<Type> & r) {unite(r);}
void operator &=(const PIRect<Type> & r) {intersect(r);}
PIRect<Type> operator +(const PIPoint<Type> & p) {return PIRect<Type>(*this).translated(p);}
PIRect<Type> operator -(const PIPoint<Type> & p) {return PIRect<Type>(*this).translated(-p);}
PIRect<Type> operator |(const PIRect<Type> & r) {return PIRect<Type>(*this).united(r);}
PIRect<Type> operator &(const PIRect<Type> & r) {return PIRect<Type>(*this).intersected(r);}
bool operator ==(const PIRect<Type> & r) const {return (x0 == r.x0 && y0 == r.y0 && x1 == r.x1 && y1 == r.y10);}
bool operator !=(const PIRect<Type> & r) const {return (x0 != r.x0 || y0 != r.y0 || x1 != r.x1 || y1 != r.y10);}
};
template<typename Type>
PICout operator <<(PICout & s, const PIRect<Type> & v) {s.setControl(0, true); s << "Rect{" << v.x0 << ", " << v.y0 << "; " << v.x1 - v.x0 << ", " << v.y1 - v.y0 << "}"; s.restoreControl(); return s;}
typedef PIRect<int> PIRecti;
typedef PIRect<uint> PIRectu;
typedef PIRect<float> PIRectf;
typedef PIRect<double> PIRectd;
#endif // PIGEOMETRY_H #endif // PIGEOMETRY_H

179
libs/main/math/piline.h Normal file
View File

@@ -0,0 +1,179 @@
/*! \file pirect.h
* \ingroup Math
* \brief
* \~english Two-dimensional line class
* \~russian Класс отрезка двумерной линии
* * \~\authors
* \~english
* Ivan Pelipenko peri4ko@yandex.ru;
* Andrey Bychkov work.a.b@yandex.ru;
* \~russian
* Иван Пелипенко peri4ko@yandex.ru;
* Андрей Бычков work.a.b@yandex.ru;
*/
/*
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"
/*! \brief
* \~english Two-dimensional line class
* \~russian Класс отрезка двумерной линии
* \~\details
* \~russian
* Этот класс описывает линию на плоскости в прямоугольной системе координат
*/
template<typename Type>
class PIP_EXPORT PILine {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
PIPoint<Type> p0;
PIPoint<Type> p1;
//!
PILine() {}
//!
PILine(const PIPoint<Type> & p0_, const PIPoint<Type> & p1_) {
p0 = p0_;
p1 = p1_;
}
//!
PILine(Type x0, Type y0, Type x1, Type y1) {
p0.set(x0, y0);
p1.set(x1, y1);
}
//!
PILine<Type> & set(const PIPoint<Type> & p0_, const PIPoint<Type> & p1_) {
p0 = p0_;
p1 = p1_;
return *this;
}
//!
PILine<Type> & set(Type x0, Type y0, Type x1, Type y1) {
p0.set(x0, y0);
p1.set(x1, y1);
return *this;
}
//!
bool isEmpty() const {
return (p0 == p1);
}
//!
Type width() const {return piAbs<Type>(p1.x - p0.x);}
//!
Type height() const {return piAbs<Type>(p1.y - p0.y);}
//!
PILine<Type> & translate(Type x, Type y) {
p0.translate(x, y);
p1.translate(x, y);
return *this;
}
//!
PILine<Type> & translate(const PIPoint<Type> & p) {
p0.translate(p);
p1.translate(p);
return *this;
}
//!
PILine<Type> translated(Type x, Type y) const {
PILine<Type> l(*this);
l.translate(x, y);
return l;
}
//!
PILine<Type> translated(const PIPoint<Type> & p) const {
PILine<Type> l(*this);
l.translate(p);
return l;
}
//!
PILine<Type> & move(Type x, Type y) {return translate(x, y);}
//!
PILine<Type> & move(const PIPoint<Type> & p) {return translate(p);}
//!
PILine<Type> moved(Type x, Type y) const {
PILine<Type> l(*this);
l.translate(x, y);
return l;
}
//!
PILine<Type> moved(const PIPoint<Type> & p) const {
PILine<Type> l(*this);
l.translate(p);
return l;
}
//!
void operator +=(Type x) {translate(x, x);}
//!
void operator +=(const PIPoint<Type> & p) {translate(p);}
//!
void operator -=(Type x) {translate(-x, -x);}
//!
void operator -=(const PIPoint<Type> & p) {translate(-p);}
//!
PILine<Type> operator +(const PIPoint<Type> & p) {return translated(p);}
//!
PILine<Type> operator -(const PIPoint<Type> & p) {return translated(-p);}
//!
bool operator ==(const PILine<Type> & r) const {return (p0 == r.p0 && p1 == r.p1);}
//!
bool operator !=(const PILine<Type> & r) const {return (p1 != r.p1 || p1 != r.p1);}
};
template<typename Type>
PICout operator <<(PICout & s, const PILine<Type> & v) {
s.setControl(0, true);
s << "Line{" << v.p0 << ", " << v.p1 << "}";
s.restoreControl();
return s;
}
typedef PILine<int> PILinei;
typedef PILine<uint> PILineu;
typedef PILine<float> PILinef;
typedef PILine<double> PILined;
#endif // PILINE_H

View File

@@ -471,5 +471,5 @@ double randomn(double dv, double sv) {
double randomd() { double randomd() {
return (double) randomi() / RAND_MAX * 2. - 1.; return (double) rand() / RAND_MAX * 2. - 1.;
} }

View File

@@ -1,10 +1,20 @@
/*! @file pimathbase.h /*! \file pimathbase.h
* @brief Basic mathematical functions and defines * \defgroup Math
* \brief
* \~english Basic mathematical functions and defines
* \~russian Базовые математические функции и дефайны
* \~\authors
* \~english
* Ivan Pelipenko peri4ko@yandex.ru;
* Andrey Bychkov work.a.b@yandex.ru;
* \~russian
* Иван Пелипенко peri4ko@yandex.ru;
* Андрей Бычков work.a.b@yandex.ru;
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Basic mathematical functions and defines Basic mathematical functions and defines
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by

164
libs/main/math/pipoint.h Normal file
View File

@@ -0,0 +1,164 @@
//! \file pipoint.h
//! \ingroup Math
//! \brief
//! \~english Two-dimensional point class
//! \~russian Класс двумерной точки
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
/*
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 Класс двумерной точки
template<typename Type>
class PIP_EXPORT PIPoint {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
Type x;
Type y;
//!
PIPoint() {x = y = Type();}
//!
PIPoint(Type x_, Type y_) {set(x_, y_);}
//!
PIPoint<Type> & set(Type x_, Type y_) {
x = x_;
y = y_;
return *this;
}
//!
PIPoint<Type> & set(const PIPoint<Type> & p) {
x = p.x;
y = p.y;
return *this;
}
//!
PIPoint<Type> & translate(Type x_, Type y_) {
x += x_;
y += y_;
return *this;
}
//!
PIPoint<Type> & translate(const PIPoint<Type> & p) {
x += p.x;
y += p.y;
return *this;
}
//!
PIPoint<Type> translated(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//!
PIPoint<Type> translated(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//!
PIPoint<Type> & move(Type x_, Type y_) {return translate(x_, y_);}
//!
PIPoint<Type> & move(const PIPoint<Type> & p) {return translate(p);}
//!
PIPoint<Type> moved(Type x_, Type y_) const {
PIPoint<Type> rp(*this);
rp.translate(x_, y_);
return rp;
}
//!
PIPoint<Type> moved(const PIPoint<Type> & p) const {
PIPoint<Type> rp(*this);
rp.translate(p);
return rp;
}
//!
double angleRad() const {return atan2(y, x);}
//!
double angleDeg() const {return toDeg(atan2(y, x));}
//!
PIPoint<Type> toPolar(bool isDeg = false) const {return PIPoint<Type>(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());}
//!
static PIPoint<Type> fromPolar(const PIPoint<Type> & p) {return PIPoint<Type>(p.y * cos(p.x), p.y * sin(p.x));}
//!
void operator +=(const PIPoint<Type> & p) {translate(p);}
//!
PIPoint<Type> operator +(const PIPoint<Type> & p) {return PIPoint<Type>(x + p.x, y + p.y);}
//!
PIPoint<Type> operator +(const Type & p) {return PIPoint<Type>(x + p, y + p);}
//!
PIPoint<Type> operator -(const PIPoint<Type> & p) {return PIPoint<Type>(x - p.x, y - p.y);}
//!
PIPoint<Type> operator -(const Type & p) {return PIPoint<Type>(x - p, y - p);}
//!
PIPoint<Type> operator -() {return PIPoint<Type>(-x, -y);}
//!
bool operator ==(const PIPoint<Type> & p) const {return (x == p.x && y == p.y);}
//!
bool operator !=(const PIPoint<Type> & p) const {return (x != p.x || y != p.y);}
};
template<typename Type>
PICout operator <<(PICout & s, const PIPoint<Type> & v) {
s.setControl(0, true);
s << "Point{" << v.x << ", " << v.y << "}";
s.restoreControl();
return s;
}
typedef PIPoint<int> PIPointi;
typedef PIPoint<uint> PIPointu;
typedef PIPoint<float> PIPointf;
typedef PIPoint<double> PIPointd;
#endif // PIPOINT_H

363
libs/main/math/pirect.h Normal file
View File

@@ -0,0 +1,363 @@
//! \file pirect.h
//! \ingroup Math
//! \brief
//! \~english Rect class
//! \~russian Класс прямоугольника
//! \~\authors
//! \~english
//! Ivan Pelipenko peri4ko@yandex.ru;
//! Andrey Bychkov work.a.b@yandex.ru;
//! \~russian
//! Иван Пелипенко peri4ko@yandex.ru;
//! Андрей Бычков work.a.b@yandex.ru;
/*
PIP - Platform Independent Primitives
Rect 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 PIRECT_H
#define PIRECT_H
#include "pipoint.h"
//! \brief
//! \~english Rect class
//! \~russian Класс прямоугольника
//! \~\details
//! \~russian
//! Этот класс описывает прямоугольник на плоскости в прямоугольной системе координат
template<typename Type>
class PIP_EXPORT PIRect {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public:
//!
PIRect() {}
//! \brief
//! \~russian Конструктор прямоугольника из координат левого нижнего угла и размеров ширины и высоты
PIRect(Type left_, Type bottom_, Type width_, Type height_) {
set(left_, bottom_, width_, height_);
normalize();
}
//! \brief
//! \~russian Конструктор прямоугольника из координат левого нижнего угла и правого верхнего угла
PIRect(const PIPoint<Type> & bottom_left, const PIPoint<Type> & top_right) {
bl = bottom_left;
tr = top_right;
normalize();
}
// PIRect(const PIPoint<Type> & p0, const PIPoint<Type> & p1, const PIPoint<Type> & p2) {
// set(piMin<Type>(p0.x, p1.x, p2.x), piMin<Type>(p0.y, p1.y, p2.y),
// piMax<Type>(p0.x, p1.x, p2.x), piMax<Type>(p0.y, p1.y, p2.y));
// }
//!
PIRect<Type> & set(Type left_, Type bottom_, Type width_, Type height_) {
bl = PIPoint<Type>(left_, bottom_);
tr = PIPoint<Type>(left_ + width_, bottom_ + height_);
return normalize();
}
//!
PIRect<Type> & set(const PIPoint<Type> & top_left, const PIPoint<Type> & bottom_right) {
bl = top_left;
tr = bottom_right;
return normalize();
}
//! \brief
//! \~russian Возвращает true если точка с указанными координатами принадлежит прямоугольнику
bool pointIn(Type x, Type y) const {
return (x <= bl.x && x >= tr.x && y <= bl.y && y >= tr.y);
}
//! \brief
//! \~russian Возвращает true если точка с указанными координатами принадлежит прямоугольнику
bool pointIn(const PIPoint<Type> & p) const {
return pointIn(p.x, p.y);
}
//!
bool isEmpty() const {
return (width() == 0 && height() == 0);
}
//!
PIRect<Type> & translate(Type x, Type y) {
bl.translate(x, y);
tr.translate(x, y);
return *this;
}
//!
PIRect<Type> & translate(const PIPoint<Type> & p) {
bl.translate(p);
tr.translate(p);
return *this;
}
//!
PIRect<Type> translated(Type x, Type y) const {
PIRect<Type> r(*this);
r.translate(x, y);
return r;
}
//!
PIRect<Type> translated(const PIPoint<Type> & p) const {
PIRect<Type> r(*this);
r.translate(p);
return r;
}
//!
PIRect<Type> & move(Type x, Type y) {return translate(x, y);}
//!
PIRect<Type> & move(const PIPoint<Type> & p) {return translate(p);}
//!
PIRect<Type> moved(Type x, Type y) const {
PIRect<Type> r(*this);
r.translate(x, y);
return r;
}
//!
PIRect<Type> moved(const PIPoint<Type> & p) const {
PIRect<Type> r(*this);
r.translate(p);
return r;
}
//!
PIRect<Type> & scale(Type x, Type y) {
setWidth(width() * x);
setHeight(height() * y);
return normalize();
}
//!
PIRect<Type> & scale(Type s) {return scale(s, s);}
//!
PIRect<Type> & scale(const PIPoint<Type> & p) {return scale(p.x, p.y);}
//!
PIRect<Type> scaled(Type x, Type y) const {
PIRect<Type> r(*this);
r.scale(x, y);
return r;
}
//!
PIRect<Type> scaled(Type s) const {
PIRect<Type> r(*this);
r.scale(s);
return r;
}
//!
PIRect<Type> scaled(const PIPoint<Type> & p) const {
PIRect<Type> r(*this);
r.scale(p);
return r;
}
//!
PIRect<Type> & normalize() {
if (bl.x > tr.x) piSwap<Type>(bl.x, tr.x);
if (bl.y > tr.y) piSwap<Type>(bl.y, tr.y);
return *this;
}
//!
PIRect<Type> normalized() const {
PIRect<Type> r(*this);
r.normalize();
return r;
}
//!
PIRect<Type> & unite(const PIRect<Type> & r) {
bl.x = piMax<Type>(bl.x, r.left());
bl.y = piMax<Type>(bl.y, r.bottom());
tr.x = piMin<Type>(tr.x, r.right());
tr.y = piMin<Type>(tr.y, r.top());
return normalize();
}
//!
PIRect<Type> united(const PIRect<Type> & rect) const {
PIRect<Type> r(*this);
r.unite(rect);
return r;
}
//!
PIRect<Type> & intersect(const PIRect<Type> & r) {
bl.x = piMax<Type>(bl.x, r.left());
bl.y = piMax<Type>(bl.y, r.bottom());
tr.x = piMin<Type>(tr.x, r.right());
tr.y = piMin<Type>(tr.y, r.top());
if (bl.x > tr.x || bl.y > tr.y) bl = tr = PIPoint<Type>();
return *this;
}
//!
PIRect<Type> intersected(const PIRect<Type> & rect) const {
PIRect<Type> r(*this);
r.intersect(rect);
return r;
}
//!
Type top() const {return tr.y;}
//!
Type left() const {return bl.x;}
//!
Type right() const {return tr.x;}
//!
Type bottom() const {return bl.y;}
//!
Type width() const {return tr.x - bl.x;}
//!
Type height() const {return tr.y - bl.y;}
//!
PIPoint<Type> topLeft() const {return PIPoint<Type>(bl.x, tr.y);}
//!
PIPoint<Type> topRigth() const {return tr;}
//!
PIPoint<Type> bottomLeft() const {return bl;}
//!
PIPoint<Type> bottomRight() const {return PIPoint<Type>(tr.x, bl.y);}
//!
PIPoint<Type> center() const {return bl.moved(width()/2, height()/2);}
//!
void setTop(Type v) {tr.y = v; normalize();}
//!
void setLeft(Type v) {bl.x = v; normalize();}
//!
void setRigth(Type v) {tr.x = v; normalize();}
//!
void setBottom(Type v) {bl.y = v; normalize();}
//!
void setWidth(Type v) {setTop(bl.x + v);}
//!
void setHeight(Type v) {setRigth(bl.y + v);}
//!
void setTopLeft(const PIPoint<Type> & p) {setLeft(p.x); setTop(p.y);}
//!
void setBottomRight(const PIPoint<Type> & p) {setRigth(p.x); setBottom(p.y);}
//!
void setBottomLeft(const PIPoint<Type> & p) {bl = p; normalize();}
//!
void setTopRigth(const PIPoint<Type> & p) {tr = p; normalize();}
//!
void setCenter(const PIPoint<Type> & p) {
Type w = width();
Type h = height();
bl = p.translated(-w/2, -h/2);
tr = PIPoint<Type>(bl.x + w, bl.y + h);
}
//!
void setSize(Type w, Type h) {
tr = PIPoint<Type>(bl.x + w, bl.y + h);
normalize();
}
//!
void operator +=(Type x) {translate(x, x);}
//!
void operator +=(const PIPoint<Type> & p) {translate(p);}
//!
void operator -=(Type x) {translate(-x, -x);}
//!
void operator -=(const PIPoint<Type> & p) {translate(-p);}
//!
void operator |=(const PIRect<Type> & r) {unite(r);}
//!
void operator &=(const PIRect<Type> & r) {intersect(r);}
//!
PIRect<Type> operator +(const PIPoint<Type> & p) {return translated(p);}
//!
PIRect<Type> operator -(const PIPoint<Type> & p) {return translated(-p);}
//!
PIRect<Type> operator |(const PIRect<Type> & r) {return united(r);}
//!
PIRect<Type> operator &(const PIRect<Type> & r) {return intersected(r);}
//!
bool operator ==(const PIRect<Type> & r) const {return (bl == r.bl && tr == r.tr);}
//!
bool operator !=(const PIRect<Type> & r) const {return (bl != r.bl || tr != r.tr);}
private:
PIPoint<Type> bl;
PIPoint<Type> tr;
};
template<typename Type>
PICout operator <<(PICout & s, const PIRect<Type> & v) {
s.setControl(0, true);
s << "Rect{" << v.bottomLeft() << ":" << v.width() << "x" << v.height() << "}";
s.restoreControl();
return s;
}
typedef PIRect<int> PIRecti;
typedef PIRect<uint> PIRectu;
typedef PIRect<float> PIRectf;
typedef PIRect<double> PIRectd;
#endif // PIRECT_H