PIRect complete

This commit is contained in:
Andrey
2022-03-21 10:35:34 +03:00
parent 2596b119ac
commit 3dd0d0b6cf
7 changed files with 160 additions and 57 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

@@ -38,11 +38,25 @@ template<typename Type>
class PIP_EXPORT PILine { class PIP_EXPORT PILine {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic"); static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public: public:
PIPoint p0; PIPoint<Type> p0;
PIPoint p1; PIPoint<Type> p1;
PILine() {} PILine() {}
PILine(const PIPoint<Type> & p0_, const PIPoint<Type> & p1_) {
p0 = p0_;
p1 = p1_;
}
bool isEmpty() const {
return (p0 == p1);
}
}; };
typedef PILine<int> PILinei;
typedef PILine<uint> PILineu;
typedef PILine<float> PILinef;
typedef PILine<double> PILined;
#endif // PILINE_H #endif // PILINE_H

View File

@@ -65,8 +65,28 @@ public:
y += p.y; y += p.y;
return *this; 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(Type x_, Type y_) {return translate(x_, y_);}
PIPoint<Type> & move(const PIPoint<Type> & p) {return translate(p);} 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 angleRad() const {return atan2(y, x);}
double angleDeg() const {return toDeg(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());} PIPoint<Type> toPolar(bool isDeg = false) const {return PIPoint<Type>(sqrt(x*x + y*y), isDeg ? angleDeg() : angleRad());}

View File

@@ -3,7 +3,7 @@
* \brief * \brief
* \~english Rect class * \~english Rect class
* \~russian Класс прямоугольника * \~russian Класс прямоугольника
* * \~\authors * \~\authors
* \~english * \~english
* Ivan Pelipenko peri4ko@yandex.ru; * Ivan Pelipenko peri4ko@yandex.ru;
* Andrey Bychkov work.a.b@yandex.ru; * Andrey Bychkov work.a.b@yandex.ru;
@@ -37,37 +37,47 @@
/*! \brief /*! \brief
* \~english Rect class * \~english Rect class
* \~russian Класс прямоугольника * \~russian Класс прямоугольника
* \~\details
* \~russian
* Этот класс описывает прямоугольник на плоскости в прямоугольной системе координат
*/ */
template<typename Type> template<typename Type>
class PIP_EXPORT PIRect { class PIP_EXPORT PIRect {
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic"); static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
public: public:
PIRect() {} 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(); normalize();
} }
PIRect(const PIPoint<Type> & top_left, const PIPoint<Type> & bottom_right) { /*! \brief
tl = top_left; * \~russian Конструктор прямоугольника из координат левого нижнего угла и правого верхнего угла
br = bottom_right; */
PIRect(const PIPoint<Type> & bottom_left, const PIPoint<Type> & top_right) {
bl = bottom_left;
tr = top_right;
normalize(); normalize();
} }
// PIRect(const PIPoint<Type> & p0, const PIPoint<Type> & p1, const PIPoint<Type> & p2) { // 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), // 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)); // 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) { PIRect<Type> & set(Type left_, Type bottom_, Type width_, Type height_) {
tl = PIPoint<Type>(x, y); bl = PIPoint<Type>(left_, bottom_);
br = PIPoint<Type>(x + w, y + h); tr = PIPoint<Type>(left_ + width_, bottom_ + height_);
return normalize(); return normalize();
} }
PIRect<Type> & set(const PIPoint<Type> & top_left, const PIPoint<Type> & bottom_right) { PIRect<Type> & set(const PIPoint<Type> & top_left, const PIPoint<Type> & bottom_right) {
tl = top_left; bl = top_left;
br = bottom_right; tr = bottom_right;
return normalize(); return normalize();
} }
bool pointIn(Type x, Type y) const { 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<Type> & p) const { bool pointIn(const PIPoint<Type> & p) const {
return pointIn(p.x, p.y); return pointIn(p.x, p.y);
@@ -76,13 +86,13 @@ public:
return (width() == 0 && height() == 0); return (width() == 0 && height() == 0);
} }
PIRect<Type> & translate(Type x, Type y) { PIRect<Type> & translate(Type x, Type y) {
tl.translate(x, y); bl.translate(x, y);
br.translate(x, y); tr.translate(x, y);
return *this; return *this;
} }
PIRect<Type> & translate(const PIPoint<Type> & p) { PIRect<Type> & translate(const PIPoint<Type> & p) {
tl.translate(p); bl.translate(p);
br.translate(p); tr.translate(p);
return *this; return *this;
} }
PIRect<Type> translated(Type x, Type y) const { PIRect<Type> translated(Type x, Type y) const {
@@ -95,10 +105,22 @@ public:
r.translate(p); r.translate(p);
return r; 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) { PIRect<Type> & scale(Type x, Type y) {
setWidth(width() * x); setWidth(width() * x);
setHeight(height() * y); setHeight(height() * y);
return *this; return normalize();
} }
PIRect<Type> & scale(Type s) {return scale(s, s);} PIRect<Type> & scale(Type s) {return scale(s, s);}
PIRect<Type> & scale(const PIPoint<Type> & p) {return scale(p.x, p.y);} PIRect<Type> & scale(const PIPoint<Type> & p) {return scale(p.x, p.y);}
@@ -118,8 +140,8 @@ public:
return r; return r;
} }
PIRect<Type> & normalize() { PIRect<Type> & normalize() {
if (tl.x > br.x) piSwap<Type>(tl.x, br.x); if (bl.x > tr.x) piSwap<Type>(bl.x, tr.x);
if (tl.y > br.y) piSwap<Type>(tl.y, br.y); if (bl.y > tr.y) piSwap<Type>(bl.y, tr.y);
return *this; return *this;
} }
PIRect<Type> normalized() const { PIRect<Type> normalized() const {
@@ -128,10 +150,10 @@ public:
return r; return r;
} }
PIRect<Type> & unite(const PIRect<Type> & r) { PIRect<Type> & unite(const PIRect<Type> & r) {
tl.x = piMax<Type>(tl.x, r.left()); bl.x = piMax<Type>(bl.x, r.left());
tl.y = piMax<Type>(tl.y, r.top()); bl.y = piMax<Type>(bl.y, r.bottom());
br.x = piMin<Type>(br.x, r.right()); tr.x = piMin<Type>(tr.x, r.right());
br.y = piMin<Type>(br.y, r.bottom()); tr.y = piMin<Type>(tr.y, r.top());
return normalize(); return normalize();
} }
PIRect<Type> united(const PIRect<Type> & rect) const { PIRect<Type> united(const PIRect<Type> & rect) const {
@@ -139,28 +161,51 @@ public:
r.unite(rect); r.unite(rect);
return r; 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> & intersect(const PIRect<Type> & r) {
PIRect<Type> intersected(const PIRect<Type> & rect) const {PIRect<Type> r(*this); r.intersect(rect); return r;} bl.x = piMax<Type>(bl.x, r.left());
Type top() const {return tl.y;} bl.y = piMax<Type>(bl.y, r.bottom());
Type left() const {return x0;} tr.x = piMin<Type>(tr.x, r.right());
Type right() const {return x1;} tr.y = piMin<Type>(tr.y, r.top());
Type bottom() const {return y1;} if (bl.x > tr.x || bl.y > tr.y) bl = tr = PIPoint<Type>();
Type width() const {return x1 - x0;} return *this;
Type height() const {return y1 - y0;} }
PIPoint<Type> topLeft() const {return tl;} PIRect<Type> intersected(const PIRect<Type> & rect) const {
PIPoint<Type> topRigth() const {return PIPoint<Type>(p1.x, p0.y);} PIRect<Type> r(*this);
PIPoint<Type> bottomLeft() const {return PIPoint<Type>(x0, y1);} r.intersect(rect);
PIPoint<Type> bottomRight() const {return br;} return r;
void setTop(Type v) {y0 = v;} }
void setLeft(Type v) {x0 = v;} Type top() const {return tr.y;}
void setRigth(Type v) {x1 = v;} Type left() const {return bl.x;}
void setBottom(Type v) {y1 = v;} Type right() const {return tr.x;}
void setWidth(Type v) {x1 = x0 + v;} Type bottom() const {return bl.y;}
void setHeight(Type v) {y1 = y0 + v;} Type width() const {return tr.x - bl.x;}
void setTopLeft(const PIPoint<Type> & p) {p0 = p;} Type height() const {return tr.y - bl.y;}
void bottomRight(const PIPoint<Type> & p) {p0 = p;} 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();
}
PIRect<Type> operator -() {return PIRect<Type>(-x0, -y0, -width(), -height());}
void operator +=(Type x) {translate(x, x);} void operator +=(Type x) {translate(x, x);}
void operator +=(const PIPoint<Type> & p) {translate(p);} void operator +=(const PIPoint<Type> & p) {translate(p);}
void operator -=(Type x) {translate(-x, -x);} void operator -=(Type x) {translate(-x, -x);}
@@ -171,18 +216,18 @@ public:
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 united(r);}
PIRect<Type> operator &(const PIRect<Type> & r) {return intersected(r);} PIRect<Type> operator &(const PIRect<Type> & r) {return 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 (bl == r.bl && tr == r.tr);}
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 (bl != r.bl || tr != r.tr);}
private: private:
PIPoint<Type> tl; PIPoint<Type> bl;
PIPoint<Type> br; PIPoint<Type> tr;
}; };
template<typename Type> template<typename Type>
PICout operator <<(PICout & s, const PIRect<Type> & v) { PICout operator <<(PICout & s, const PIRect<Type> & v) {
s.setControl(0, true); s.setControl(0, true);
s << "Rect{" << v.topLeft() << "," << v.width() << "x" << v.height() << "}"; s << "Rect{" << v.bottomLeft() << ":" << v.width() << "x" << v.height() << "}";
s.restoreControl(); s.restoreControl();
return s; return s;
} }