diff --git a/CMakeLists.txt b/CMakeLists.txt index 1df09d3c..7a6d7a99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 33) -set(pip_REVISION 1) +set(pip_MINOR 34) +set(pip_REVISION 0) set(pip_SUFFIX ) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) diff --git a/doc/images/pirect.png b/doc/images/pirect.png new file mode 100644 index 00000000..a1b8b105 Binary files /dev/null and b/doc/images/pirect.png differ diff --git a/libs/main/core/pivariant.cpp b/libs/main/core/pivariant.cpp index 3eda416f..98d1eb4e 100644 --- a/libs/main/core/pivariant.cpp +++ b/libs/main/core/pivariant.cpp @@ -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 * \details In case of PIMathVectord type returns rect value. \n * In case of other types returns empty PIMathVectord. */ diff --git a/libs/main/core/pivariant.h b/libs/main/core/pivariant.h index fe155eef..0db863d8 100644 --- a/libs/main/core/pivariant.h +++ b/libs/main/core/pivariant.h @@ -234,11 +234,12 @@ public: pivFile /** PIVariantTypes::File */ , pivDir /** PIVariantTypes::Dir */ , pivColor /** PIVariantTypes::Color */ , - pivPoint /** PIPoint */ , - pivRect /** PIRect */ , + pivPoint /** PIPoint */ , + pivRect /** PIRect */ , pivIODevice /** PIVariantTypes::IODevice */ , - pivMathVector /** PIMathVectord */ , - pivMathMatrix /** PIMathMatrixd */ , + pivMathVector /** PIMathVector */ , + pivMathMatrix /** PIMathMatrix */ , + pivLine /** PILine */ , pivCustom /** Custom */ = 0xFF }; @@ -333,6 +334,9 @@ public: //! Constructs variant from rect PIVariant(const PIRectd & v) {initType(v);} + //! Constructs variant from line + PIVariant(const PILined & v) {initType(v);} + //! Constructs variant from MathVector PIVariant(const PIMathVectord & v) {initType(v);} @@ -424,6 +428,9 @@ public: //! Set variant content and type to rect 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 void setValue(const PIMathVectord & v) {initType(v);} @@ -456,6 +463,7 @@ public: PIVariantTypes::IODevice toIODevice() const; PIPointd toPoint() const; PIRectd toRect() const; + PILined toLine() const; PIMathVectord toMathVector() const; PIMathMatrixd toMathMatrix() const; @@ -527,6 +535,8 @@ public: //! Assign operator PIVariant & operator =(const PIRectd & v) {setValue(v); return *this;} //! Assign operator + PIVariant & operator =(const PILined & v) {setValue(v); return *this;} + //! Assign operator PIVariant & operator =(const PIMathVectord & v) {setValue(v); return *this;} //! Assign operator 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 PIPointd PIVariant::value() const {return toPoint();} 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::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 PIPointd & 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 PIMathMatrixd & 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() {r template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivIODevice;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivPoint;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivRect;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivLine;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivMathVector;} template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::pivMathMatrix;} @@ -751,6 +764,7 @@ REGISTER_NS_VARIANT(PIVariantTypes, Color) REGISTER_NS_VARIANT(PIVariantTypes, IODevice) REGISTER_VARIANT(PIPointd) REGISTER_VARIANT(PIRectd) +REGISTER_VARIANT(PILined) REGISTER_VARIANT(PIMathVectord) REGISTER_VARIANT(PIMathMatrixd) diff --git a/libs/main/math/piline.h b/libs/main/math/piline.h index 4697e98a..03c489fa 100644 --- a/libs/main/math/piline.h +++ b/libs/main/math/piline.h @@ -38,11 +38,25 @@ template class PIP_EXPORT PILine { static_assert(std::is_arithmetic::value, "Type must be arithmetic"); public: - PIPoint p0; - PIPoint p1; + PIPoint p0; + PIPoint p1; PILine() {} + PILine(const PIPoint & p0_, const PIPoint & p1_) { + p0 = p0_; + p1 = p1_; + } + + bool isEmpty() const { + return (p0 == p1); + } }; + +typedef PILine PILinei; +typedef PILine PILineu; +typedef PILine PILinef; +typedef PILine PILined; + #endif // PILINE_H diff --git a/libs/main/math/pipoint.h b/libs/main/math/pipoint.h index 660bbdcd..401518a4 100644 --- a/libs/main/math/pipoint.h +++ b/libs/main/math/pipoint.h @@ -65,8 +65,28 @@ public: y += p.y; return *this; } + PIPoint translated(Type x_, Type y_) const { + PIPoint rp(*this); + rp.translate(x_, y_); + return rp; + } + PIPoint translated(const PIPoint & p) const { + PIPoint rp(*this); + rp.translate(p); + return rp; + } PIPoint & move(Type x_, Type y_) {return translate(x_, y_);} PIPoint & move(const PIPoint & p) {return translate(p);} + PIPoint moved(Type x_, Type y_) const { + PIPoint rp(*this); + rp.translate(x_, y_); + return rp; + } + PIPoint moved(const PIPoint & p) const { + PIPoint rp(*this); + rp.translate(p); + return rp; + } 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());} diff --git a/libs/main/math/pirect.h b/libs/main/math/pirect.h index b0eabe95..6f82cdad 100644 --- a/libs/main/math/pirect.h +++ b/libs/main/math/pirect.h @@ -3,7 +3,7 @@ * \brief * \~english Rect class * \~russian Класс прямоугольника - * * \~\authors + * \~\authors * \~english * Ivan Pelipenko peri4ko@yandex.ru; * Andrey Bychkov work.a.b@yandex.ru; @@ -37,37 +37,47 @@ /*! \brief * \~english Rect class * \~russian Класс прямоугольника + * \~\details + * \~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); + + /*! \brief + * \~russian Конструктор прямоугольника из координат левого нижнего угла и размеров ширины и высоты + */ + PIRect(Type left_, Type bottom_, Type width_, Type height_) { + set(left_, bottom_, width_, height_); normalize(); } - PIRect(const PIPoint & top_left, const PIPoint & bottom_right) { - tl = top_left; - br = bottom_right; + /*! \brief + * \~russian Конструктор прямоугольника из координат левого нижнего угла и правого верхнего угла + */ + PIRect(const PIPoint & bottom_left, const PIPoint & top_right) { + bl = bottom_left; + tr = top_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); + PIRect & set(Type left_, Type bottom_, Type width_, Type height_) { + bl = PIPoint(left_, bottom_); + tr = PIPoint(left_ + width_, bottom_ + height_); return normalize(); } PIRect & set(const PIPoint & top_left, const PIPoint & bottom_right) { - tl = top_left; - br = bottom_right; + bl = top_left; + tr = bottom_right; return normalize(); } bool pointIn(Type x, Type y) const { - return (x <= br.x && x >= tl.x && y <= br.y && y >= tl.y); + return (x <= bl.x && x >= tr.x && y <= bl.y && y >= tr.y); } bool pointIn(const PIPoint & p) const { return pointIn(p.x, p.y); @@ -76,13 +86,13 @@ public: return (width() == 0 && height() == 0); } PIRect & translate(Type x, Type y) { - tl.translate(x, y); - br.translate(x, y); + bl.translate(x, y); + tr.translate(x, y); return *this; } PIRect & translate(const PIPoint & p) { - tl.translate(p); - br.translate(p); + bl.translate(p); + tr.translate(p); return *this; } PIRect translated(Type x, Type y) const { @@ -95,10 +105,22 @@ public: r.translate(p); return r; } + PIRect & move(Type x, Type y) {return translate(x, y);} + PIRect & move(const PIPoint & p) {return translate(p);} + PIRect moved(Type x, Type y) const { + PIRect r(*this); + r.translate(x, y); + return r; + } + PIRect moved(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; + return normalize(); } PIRect & scale(Type s) {return scale(s, s);} PIRect & scale(const PIPoint & p) {return scale(p.x, p.y);} @@ -118,8 +140,8 @@ public: return r; } PIRect & normalize() { - if (tl.x > br.x) piSwap(tl.x, br.x); - if (tl.y > br.y) piSwap(tl.y, br.y); + if (bl.x > tr.x) piSwap(bl.x, tr.x); + if (bl.y > tr.y) piSwap(bl.y, tr.y); return *this; } PIRect normalized() const { @@ -128,10 +150,10 @@ public: 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()); + bl.x = piMax(bl.x, r.left()); + bl.y = piMax(bl.y, r.bottom()); + tr.x = piMin(tr.x, r.right()); + tr.y = piMin(tr.y, r.top()); return normalize(); } PIRect united(const PIRect & rect) const { @@ -139,28 +161,51 @@ public: 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 & intersect(const PIRect & r) { + bl.x = piMax(bl.x, r.left()); + bl.y = piMax(bl.y, r.bottom()); + tr.x = piMin(tr.x, r.right()); + tr.y = piMin(tr.y, r.top()); + if (bl.x > tr.x || bl.y > tr.y) bl = tr = PIPoint(); + return *this; + } + PIRect intersected(const PIRect & rect) const { + PIRect 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 topLeft() const {return PIPoint(bl.x, tr.y);} + PIPoint topRigth() const {return tr;} + PIPoint bottomLeft() const {return bl;} + PIPoint bottomRight() const {return PIPoint(tr.x, bl.y);} + PIPoint 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 & p) {setLeft(p.x); setTop(p.y);} + void setBottomRight(const PIPoint & p) {setRigth(p.x); setBottom(p.y);} + void setBottomLeft(const PIPoint & p) {bl = p; normalize();} + void setTopRigth(const PIPoint & p) {tr = p; normalize();} + void setCenter(const PIPoint & p) { + Type w = width(); + Type h = height(); + bl = p.translated(-w/2, -h/2); + tr = PIPoint(bl.x + w, bl.y + h); + } + void setSize(Type w, Type h) { + tr = PIPoint(bl.x + w, bl.y + h); + normalize(); + } - 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);} @@ -171,18 +216,18 @@ public: 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);} + bool operator ==(const PIRect & r) const {return (bl == r.bl && tr == r.tr);} + bool operator !=(const PIRect & r) const {return (bl != r.bl || tr != r.tr);} private: - PIPoint tl; - PIPoint br; + PIPoint bl; + PIPoint tr; }; template PICout operator <<(PICout & s, const PIRect & v) { s.setControl(0, true); - s << "Rect{" << v.topLeft() << "," << v.width() << "x" << v.height() << "}"; + s << "Rect{" << v.bottomLeft() << ":" << v.width() << "x" << v.height() << "}"; s.restoreControl(); return s; }