diff --git a/libs/main/math/pigeometry.h b/libs/main/math/pigeometry.h index 685dd03d..c3948e95 100644 --- a/libs/main/math/pigeometry.h +++ b/libs/main/math/pigeometry.h @@ -1,10 +1,25 @@ -/*! @file pigeometry.h - * @brief Geometry base class +/*! \file pigeometry.h + * \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 - Geometry - Ivan Pelipenko peri4ko@yandex.ru + Geometry base classes + 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 @@ -19,130 +34,11 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ - - #ifndef PIGEOMETRY_H #define PIGEOMETRY_H -#include "pimathbase.h" - -template -class PIP_EXPORT PIPoint { - static_assert(std::is_arithmetic::value, "Type must be arithmetic"); -public: - Type x; - Type y; - - PIPoint() {x = y = Type();} - PIPoint(Type x_, Type y_) {set(x_, y_);} - - PIPoint & set(Type x_, Type y_) {x = x_; y = y_; return *this;} - PIPoint & move(Type x_, Type y_) {x += x_; y += y_; return *this;} - PIPoint & move(const PIPoint & 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 toPolar(bool isDeg = false) const {return PIPoint(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());} - static PIPoint fromPolar(const PIPoint & p) {return PIPoint(p.y * cos(p.x), p.y * sin(p.x));} - - PIPoint operator +(const PIPoint & p) {return PIPoint(x + p.x, y + p.y);} - PIPoint operator +(const Type & p) {return PIPoint(x + p, y + p);} - PIPoint operator -(const PIPoint & p) {return PIPoint(x - p.x, y - p.y);} - PIPoint operator -(const Type & p) {return PIPoint(x - p, y - p);} - PIPoint operator -() {return PIPoint(-x, -y);} - PIPoint operator *(const Type & d) {return PIPoint(x * d, y * d);} - PIPoint operator /(const Type & d) {return PIPoint(x / d, y / d);} - bool operator ==(const PIPoint & p) const {return (x == p.x && y == p.y);} - bool operator !=(const PIPoint & p) const {return (x != p.x || y != p.y);} - -}; - -template -PICout operator <<(PICout & s, const PIPoint & v) {s.setControl(0, true); s << "Point{" << v.x << ", " << v.y << "}"; s.restoreControl(); return s;} - - -typedef PIPoint PIPointi; -typedef PIPoint PIPointu; -typedef PIPoint PIPointf; -typedef PIPoint PIPointd; - - - - -template -class PIP_EXPORT PIRect { - static_assert(std::is_arithmetic::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 & tl, const PIPoint & br) {set(tl.x, tl.y, br.x, br.y);} - PIRect(const PIPoint & p0, const PIPoint & p1, const PIPoint & p2) {set(piMin(p0.x, p1.x, p2.x), piMin(p0.y, p1.y, p2.y), - piMax(p0.x, p1.x, p2.x), piMax(p0.y, p1.y, p2.y));} - - PIRect & 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 & p) const {return pointIn(p.x, p.y);} - bool isEmpty() const {return (x1 - x0 == 0 && y1 - y0 == 0);} - PIRect & translate(Type x, Type y) {x0 += x; x1 += x; y0 += y; y1 += y; return *this;} - PIRect & translate(const PIPoint & p) {x0 += p.x; x1 += p.x; y0 += p.y; y1 += p.y; return *this;} - PIRect translated(Type x, Type y) {PIRect r(*this); r.translate(x, y); return r;} - PIRect translated(const PIPoint & p) {PIRect r(*this); r.translate(p); return r;} - PIRect & scale(Type x, Type y) {setWidth(width() * x); setHeight(height() * y); return *this;} - PIRect & scale(const PIPoint & p) {setWidth(width() * p.x); setHeight(height() * p.y); return *this;} - PIRect scaled(Type x, Type y) {PIRect r(*this); r.scale(x, y); return r;} - PIRect scaled(const PIPoint & p) {PIRect r(*this); r.scale(p); return r;} - PIRect & normalize() {if (x0 > x1) piSwap(x0, x1); if (y0 > y1) piSwap(y0, y1); return *this;} - PIRect normalized() {PIRect r(*this); r.normalize(); return r;} - PIRect & unite(const PIRect & r) {x0 = piMin(x0, r.x0); y0 = piMin(y0, r.y0); x1 = piMax(x1, r.x1); y1 = piMax(y1, r.y1); return *this;} - PIRect united(const PIRect & rect) {PIRect r(*this); r.unite(rect); return r;} - PIRect & intersect(const PIRect & r) {x0 = piMax(x0, r.x0); y0 = piMax(y0, r.y0); x1 = piMin(x1, r.x1); y1 = piMin(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;} - PIRect intersected(const PIRect & rect) {PIRect 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 topLeft() {return PIPoint(x0, y0);} - PIPoint topRigth() {return PIPoint(x1, y0);} - PIPoint bottomLeft() {return PIPoint(x0, y1);} - PIPoint bottomRight() {return PIPoint(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 operator -() {return PIRect(-x0, -y0, -width(), -height());} - void operator +=(Type x) {translate(x, x);} - void operator +=(const PIPoint & p) {translate(p);} - void operator -=(Type x) {translate(-x, -x);} - void operator -=(const PIPoint & 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 & r) {unite(r);} - void operator &=(const PIRect & r) {intersect(r);} - PIRect operator +(const PIPoint & p) {return PIRect(*this).translated(p);} - PIRect operator -(const PIPoint & p) {return PIRect(*this).translated(-p);} - PIRect operator |(const PIRect & r) {return PIRect(*this).united(r);} - PIRect operator &(const PIRect & r) {return PIRect(*this).intersected(r);} - bool operator ==(const PIRect & r) const {return (x0 == r.x0 && y0 == r.y0 && x1 == r.x1 && y1 == r.y10);} - bool operator !=(const PIRect & r) const {return (x0 != r.x0 || y0 != r.y0 || x1 != r.x1 || y1 != r.y10);} - -}; - -template -PICout operator <<(PICout & s, const PIRect & 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 PIRecti; -typedef PIRect PIRectu; -typedef PIRect PIRectf; -typedef PIRect PIRectd; +#include "pipoint.h" +#include "piline.h" +#include "pirect.h" #endif // PIGEOMETRY_H diff --git a/libs/main/math/piline.h b/libs/main/math/piline.h new file mode 100644 index 00000000..4697e98a --- /dev/null +++ b/libs/main/math/piline.h @@ -0,0 +1,48 @@ +/*! \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 . +*/ +#ifndef PILINE_H +#define PILINE_H + +#include "pipoint.h" + +template +class PIP_EXPORT PILine { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); +public: + PIPoint p0; + PIPoint p1; + + PILine() {} + +}; + +#endif // PILINE_H diff --git a/libs/main/math/pimathbase.cpp b/libs/main/math/pimathbase.cpp index 42fd4acb..74a95f27 100644 --- a/libs/main/math/pimathbase.cpp +++ b/libs/main/math/pimathbase.cpp @@ -471,5 +471,5 @@ double randomn(double dv, double sv) { double randomd() { - return (double) randomi() / RAND_MAX * 2. - 1.; + return (double) rand() / RAND_MAX * 2. - 1.; } diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index 8ad5d569..30f9d605 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -1,10 +1,20 @@ -/*! @file pimathbase.h - * @brief Basic mathematical functions and defines +/*! \file pimathbase.h + * \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 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 it under the terms of the GNU Lesser General Public License as published by diff --git a/libs/main/math/pipoint.h b/libs/main/math/pipoint.h new file mode 100644 index 00000000..660bbdcd --- /dev/null +++ b/libs/main/math/pipoint.h @@ -0,0 +1,101 @@ +/*! \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 . +*/ +#ifndef PIPOINT_H +#define PIPOINT_H + +#include "pimathbase.h" + +/*! \brief + * \~english Two-dimensional point class + * \~russian Класс двумерной точки + */ +template +class PIP_EXPORT PIPoint { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); +public: + Type x; + Type y; + + PIPoint() {x = y = Type();} + PIPoint(Type x_, Type y_) {set(x_, y_);} + + PIPoint & set(Type x_, Type y_) { + x = x_; + y = y_; + return *this; + } + PIPoint & set(const PIPoint & p) { + x = p.x; + y = p.y; + return *this; + } + PIPoint & translate(Type x_, Type y_) { + x += x_; + y += y_; + return *this; + } + PIPoint & translate(const PIPoint & p) { + x += p.x; + y += p.y; + return *this; + } + PIPoint & move(Type x_, Type y_) {return translate(x_, y_);} + PIPoint & move(const PIPoint & p) {return translate(p);} + double angleRad() const {return atan2(y, x);} + double angleDeg() const {return toDeg(atan2(y, x));} + PIPoint toPolar(bool isDeg = false) const {return PIPoint(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());} + static PIPoint fromPolar(const PIPoint & p) {return PIPoint(p.y * cos(p.x), p.y * sin(p.x));} + + void operator +=(const PIPoint & p) {translate(p);} + PIPoint operator +(const PIPoint & p) {return PIPoint(x + p.x, y + p.y);} + PIPoint operator +(const Type & p) {return PIPoint(x + p, y + p);} + PIPoint operator -(const PIPoint & p) {return PIPoint(x - p.x, y - p.y);} + PIPoint operator -(const Type & p) {return PIPoint(x - p, y - p);} + PIPoint operator -() {return PIPoint(-x, -y);} + bool operator ==(const PIPoint & p) const {return (x == p.x && y == p.y);} + bool operator !=(const PIPoint & p) const {return (x != p.x || y != p.y);} + +}; + + +template +PICout operator <<(PICout & s, const PIPoint & v) { + s.setControl(0, true); + s << "Point{" << v.x << ", " << v.y << "}"; + s.restoreControl(); + return s; +} + + +typedef PIPoint PIPointi; +typedef PIPoint PIPointu; +typedef PIPoint PIPointf; +typedef PIPoint PIPointd; + +#endif // PIPOINT_H diff --git a/libs/main/math/pirect.h b/libs/main/math/pirect.h new file mode 100644 index 00000000..b0eabe95 --- /dev/null +++ b/libs/main/math/pirect.h @@ -0,0 +1,196 @@ +/*! \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 . +*/ +#ifndef PIRECT_H +#define PIRECT_H + +#include "pipoint.h" + +/*! \brief + * \~english Rect class + * \~russian Класс прямоугольника + */ +template +class PIP_EXPORT PIRect { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); +public: + PIRect() {} + PIRect(Type x, Type y, Type w, Type h) { + set(x, y, w, h); + normalize(); + } + PIRect(const PIPoint & top_left, const PIPoint & bottom_right) { + tl = top_left; + br = bottom_right; + normalize(); + } +// PIRect(const PIPoint & p0, const PIPoint & p1, const PIPoint & p2) { +// set(piMin(p0.x, p1.x, p2.x), piMin(p0.y, p1.y, p2.y), +// piMax(p0.x, p1.x, p2.x), piMax(p0.y, p1.y, p2.y)); +// } + PIRect & set(Type x, Type y, Type w, Type h) { + tl = PIPoint(x, y); + br = PIPoint(x + w, y + h); + return normalize(); + } + PIRect & set(const PIPoint & top_left, const PIPoint & bottom_right) { + tl = top_left; + br = bottom_right; + return normalize(); + } + bool pointIn(Type x, Type y) const { + return (x <= br.x && x >= tl.x && y <= br.y && y >= tl.y); + } + bool pointIn(const PIPoint & p) const { + return pointIn(p.x, p.y); + } + bool isEmpty() const { + return (width() == 0 && height() == 0); + } + PIRect & translate(Type x, Type y) { + tl.translate(x, y); + br.translate(x, y); + return *this; + } + PIRect & translate(const PIPoint & p) { + tl.translate(p); + br.translate(p); + return *this; + } + PIRect translated(Type x, Type y) const { + PIRect r(*this); + r.translate(x, y); + return r; + } + PIRect translated(const PIPoint & p) const { + PIRect r(*this); + r.translate(p); + return r; + } + PIRect & scale(Type x, Type y) { + setWidth(width() * x); + setHeight(height() * y); + return *this; + } + PIRect & scale(Type s) {return scale(s, s);} + PIRect & scale(const PIPoint & p) {return scale(p.x, p.y);} + PIRect scaled(Type x, Type y) const { + PIRect r(*this); + r.scale(x, y); + return r; + } + PIRect scaled(Type s) const { + PIRect r(*this); + r.scale(s); + return r; + } + PIRect scaled(const PIPoint & p) const { + PIRect r(*this); + r.scale(p); + return r; + } + PIRect & normalize() { + if (tl.x > br.x) piSwap(tl.x, br.x); + if (tl.y > br.y) piSwap(tl.y, br.y); + return *this; + } + PIRect normalized() const { + PIRect r(*this); + r.normalize(); + return r; + } + PIRect & unite(const PIRect & r) { + tl.x = piMax(tl.x, r.left()); + tl.y = piMax(tl.y, r.top()); + br.x = piMin(br.x, r.right()); + br.y = piMin(br.y, r.bottom()); + return normalize(); + } + PIRect united(const PIRect & rect) const { + PIRect r(*this); + r.unite(rect); + return r; + } + PIRect & intersect(const PIRect & r) {x0 = piMax(x0, r.x0); y0 = piMax(y0, r.y0); x1 = piMin(x1, r.x1); y1 = piMin(y1, r.y1); if (x0 > x1 || y0 > y1) x0 = x1 = y0 = y1 = Type(0); return *this;} + PIRect intersected(const PIRect & rect) const {PIRect r(*this); r.intersect(rect); return r;} + Type top() const {return tl.y;} + 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 topLeft() const {return tl;} + PIPoint topRigth() const {return PIPoint(p1.x, p0.y);} + PIPoint bottomLeft() const {return PIPoint(x0, y1);} + PIPoint bottomRight() const {return br;} + 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;} + void setTopLeft(const PIPoint & p) {p0 = p;} + void bottomRight(const PIPoint & p) {p0 = p;} + + PIRect operator -() {return PIRect(-x0, -y0, -width(), -height());} + void operator +=(Type x) {translate(x, x);} + void operator +=(const PIPoint & p) {translate(p);} + void operator -=(Type x) {translate(-x, -x);} + void operator -=(const PIPoint & p) {translate(-p);} + void operator |=(const PIRect & r) {unite(r);} + void operator &=(const PIRect & r) {intersect(r);} + PIRect operator +(const PIPoint & p) {return translated(p);} + PIRect operator -(const PIPoint & p) {return translated(-p);} + PIRect operator |(const PIRect & r) {return united(r);} + PIRect operator &(const PIRect & r) {return intersected(r);} + bool operator ==(const PIRect & r) const {return (x0 == r.x0 && y0 == r.y0 && x1 == r.x1 && y1 == r.y10);} + bool operator !=(const PIRect & r) const {return (x0 != r.x0 || y0 != r.y0 || x1 != r.x1 || y1 != r.y10);} + +private: + PIPoint tl; + PIPoint br; +}; + +template +PICout operator <<(PICout & s, const PIRect & v) { + s.setControl(0, true); + s << "Rect{" << v.topLeft() << "," << v.width() << "x" << v.height() << "}"; + s.restoreControl(); + return s; +} + + +typedef PIRect PIRecti; +typedef PIRect PIRectu; +typedef PIRect PIRectf; +typedef PIRect PIRectd; + +#endif // PIRECT_H