libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
rect.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <algorithm>
14#include <promeki/namespace.h>
15#include <promeki/point.h>
16#include <promeki/size2d.h>
17
18PROMEKI_NAMESPACE_BEGIN
19
42template <typename T> class Rect {
43 public:
45 Rect() = default;
46
48 Rect(const Point<T, 2> &pos, const Size2DTemplate<T> &size) : _pos(pos), _size(size) {}
49
51 Rect(T x, T y, T width, T height) : _pos(x, y), _size(width, height) {}
52
54 T x() const { return _pos.x(); }
55
57 T y() const { return _pos.y(); }
58
60 T width() const { return _size.width(); }
61
63 T height() const { return _size.height(); }
64
66 void setX(T val) { _pos.setX(val); }
67
69 void setY(T val) { _pos.setY(val); }
70
72 void setWidth(T val) { _size.setWidth(val); }
73
75 void setHeight(T val) { _size.setHeight(val); }
76
78 Point<T, 2> topLeft() const { return _pos; }
79
81 Point<T, 2> topRight() const { return Point<T, 2>(x() + width(), y()); }
82
84 Point<T, 2> bottomLeft() const { return Point<T, 2>(x(), y() + height()); }
85
87 Point<T, 2> bottomRight() const { return Point<T, 2>(x() + width(), y() + height()); }
88
90 Point<T, 2> center() const { return Point<T, 2>(x() + width() / 2, y() + height() / 2); }
91
93 const Point<T, 2> &pos() const { return _pos; }
94
96 const Size2DTemplate<T> &size() const { return _size; }
97
99 void setPos(const Point<T, 2> &p) { _pos = p; }
100
102 void setSize(const Size2DTemplate<T> &s) { _size = s; }
103
105 bool isValid() const { return _size.isValid(); }
106
108 bool isEmpty() const { return !isValid(); }
109
111 bool contains(const Point<T, 2> &p) const {
112 return p.x() >= x() && p.x() < x() + width() && p.y() >= y() && p.y() < y() + height();
113 }
114
116 bool contains(const Rect &r) const {
117 return r.x() >= x() && r.x() + r.width() <= x() + width() && r.y() >= y() &&
118 r.y() + r.height() <= y() + height();
119 }
120
122 bool intersects(const Rect &r) const {
123 return x() < r.x() + r.width() && x() + width() > r.x() && y() < r.y() + r.height() &&
124 y() + height() > r.y();
125 }
126
128 Rect intersected(const Rect &r) const {
129 T ix = std::max(x(), r.x());
130 T iy = std::max(y(), r.y());
131 T ix2 = std::min(x() + width(), r.x() + r.width());
132 T iy2 = std::min(y() + height(), r.y() + r.height());
133 if (ix2 <= ix || iy2 <= iy) return Rect();
134 return Rect(ix, iy, ix2 - ix, iy2 - iy);
135 }
136
138 Rect united(const Rect &r) const {
139 if (isEmpty()) return r;
140 if (r.isEmpty()) return *this;
141 T ux = std::min(x(), r.x());
142 T uy = std::min(y(), r.y());
143 T ux2 = std::max(x() + width(), r.x() + r.width());
144 T uy2 = std::max(y() + height(), r.y() + r.height());
145 return Rect(ux, uy, ux2 - ux, uy2 - uy);
146 }
147
149 Rect adjusted(T dx1, T dy1, T dx2, T dy2) const {
150 return Rect(x() + dx1, y() + dy1, width() + dx2 - dx1, height() + dy2 - dy1);
151 }
152
154 Rect translated(T dx, T dy) const { return Rect(x() + dx, y() + dy, width(), height()); }
155
157 bool operator==(const Rect &other) const {
158 return _pos == other._pos && _size.width() == other._size.width() &&
159 _size.height() == other._size.height();
160 }
161
163 bool operator!=(const Rect &other) const { return !(*this == other); }
164
165 private:
166 Point<T, 2> _pos;
167 Size2DTemplate<T> _size;
168};
169
171using Rect2Di32 = Rect<int32_t>;
173using Rect2Df = Rect<float>;
175using Rect2Dd = Rect<double>;
176
177PROMEKI_NAMESPACE_END
178
179#endif // PROMEKI_ENABLE_CORE