Gamedev Framework (gf) 0.22.0
A C++17 framework for 2D games
Rect.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2022 Julien Bernard
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 *
21 * Part of this file comes from SFML, with the same license:
22 * Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
23 */
24#ifndef GF_RECT_H
25#define GF_RECT_H
26
27#include <cstddef>
28#include <algorithm>
29#include <limits>
30#include <tuple>
31
32#include "Anchor.h"
33#include "CoreApi.h"
34#include "Quarter.h"
35#include "Vector.h"
36#include "VectorOps.h"
37
38namespace gf {
39#ifndef DOXYGEN_SHOULD_SKIP_THIS
40inline namespace v1 {
41#endif
42
86 template<typename T>
87 struct Rect {
93 constexpr Rect() noexcept
94 : min(gf::Zero)
95 , max(gf::Zero)
96 {
97 }
98
106 static constexpr Rect<T> fromMinMax(Vector<T, 2> min, Vector<T, 2> max) noexcept {
107 return Rect<T>(min, max);
108 }
109
117 static constexpr Rect<T> fromPositionSize(Vector<T, 2> position, Vector<T, 2> size) noexcept {
118 return Rect<T>(position, position + size);
119 }
120
129 static constexpr Rect<T> fromSize(Vector<T, 2> size) noexcept {
130 return Rect<T>({ T(0), T(0) }, size);
131 }
132
140 static constexpr Rect<T> fromCenterSize(Vector<T, 2> center, Vector<T, 2> size) noexcept {
141 return Rect<T>(center - size / T(2), center + size / T(2));
142 }
143
149 static constexpr Rect<T> empty() noexcept {
150 return Rect<T>(Vector<T, 2>(std::numeric_limits<T>::max()), Vector<T, 2>(std::numeric_limits<T>::lowest()));
151 }
152
160 constexpr Vector<T, 2> getPosition() const noexcept {
161 return min;
162 }
163
169 constexpr Vector<T, 2> getSize() const noexcept {
170 return max - min;
171 }
172
178 constexpr bool isEmpty() const noexcept {
179 return min.x >= max.x || min.y >= max.y;
180 }
181
187 constexpr Vector<T, 2> getCenter() const noexcept {
188 return min + (max - min) / 2;
189 }
190
197 constexpr bool contains(Vector<T, 2> point) const noexcept {
198 return min.x <= point.x && point.x < max.x && min.y <= point.y && point.y < max.y;
199 }
200
207 constexpr bool contains(const Rect& other) const noexcept {
208 return min.x <= other.min.x && other.max.x <= max.x && min.y <= other.min.y && other.max.y <= max.y;
209 }
210
217 constexpr bool intersects(const Rect& other) const noexcept {
218 return min.x < other.max.x && other.min.x < max.x && min.y < other.max.y && other.min.y < max.y;
219 }
220
228 constexpr bool intersects(const Rect& other, Rect& result) const noexcept {
229 if (!intersects(other)) {
230 return false;
231 }
232
233 result = getIntersection(other);
234 return true;
235 }
236
243 constexpr Rect getIntersection(const Rect& other) const noexcept {
244 Rect res;
245
246 res.min.x = std::max(min.x, other.min.x);
247 res.min.y = std::max(min.y, other.min.y);
248 res.max.x = std::min(max.x, other.max.x);
249 res.max.y = std::min(max.y, other.max.y);
250
251 return res;
252 }
253
260 constexpr T getIntersectionVolume(const Rect& other) const noexcept {
261 auto xMin = std::max(min.x, other.min.x);
262 auto xMax = std::min(max.x, other.max.x);
263
264 if (xMin >= xMax) {
265 return T(0);
266 }
267
268 auto yMin = std::max(min.y, other.min.y);
269 auto yMax = std::min(max.y, other.max.y);
270
271 if (yMin >= yMax) {
272 return T(0);
273 }
274
275 return (xMax - xMin) * (yMax - yMin);
276 }
277
284 constexpr T getIntersectionExtentLength(const Rect& other) const noexcept {
285 auto xMin = std::max(min.x, other.min.x);
286 auto xMax = std::min(max.x, other.max.x);
287
288 if (xMin >= xMax) {
289 return T(0);
290 }
291
292 auto yMin = std::max(min.y, other.min.y);
293 auto yMax = std::min(max.y, other.max.y);
294
295 if (yMin >= yMax) {
296 return T(0);
297 }
298
299 return (xMax - xMin) + (yMax - yMin);
300 }
301
307 constexpr void extend(const T (&point)[2]) noexcept {
308 min.x = std::min(min.x, point[0]);
309 min.y = std::min(min.y, point[1]);
310 max.x = std::max(max.x, point[0]);
311 max.y = std::max(max.y, point[1]);
312 }
313
319 constexpr void extend(Vector<T, 2> point) noexcept {
320 min.x = std::min(min.x, point.x);
321 min.y = std::min(min.y, point.y);
322 max.x = std::max(max.x, point.x);
323 max.y = std::max(max.y, point.y);
324 }
325
331 constexpr void extend(const Rect& other) noexcept {
332 min.x = std::min(min.x, other.min.x);
333 min.y = std::min(min.y, other.min.y);
334 max.x = std::max(max.x, other.max.x);
335 max.y = std::max(max.y, other.max.y);
336 }
337
343 constexpr Rect getExtended(const Rect& other) const noexcept {
344 Rect res(*this);
345 res.extend(other);
346 return res;
347 }
348
354 constexpr T getVolume() const noexcept {
355 return (max.x - min.x) * (max.y - min.y);
356 }
357
363 constexpr T getExtentLength() const noexcept {
364 return (max.x - min.x) + (max.y - min.y);
365 }
366
372 constexpr T getMinimumEdge() const noexcept {
373 return std::min(max.x - min.x, max.y - min.y);
374 }
375
383 constexpr Rect grow(T value) const noexcept {
384 return Rect(min - value, max + value);
385 }
386
394 constexpr Rect shrink(T value) const noexcept {
395 return Rect(min + value, max - value);
396 }
397
401 constexpr void normalize() noexcept {
402 if (min.x > max.x) { std::swap(min.x, max.x); }
403 if (min.y > max.y) { std::swap(min.y, max.y); }
404 }
405
412 constexpr Vector<T, 2> getPositionFromAnchor(Anchor anchor) const noexcept {
413 switch (anchor) {
414 case Anchor::TopLeft:
415 return this->min;
417 return { (this->min.x + this->max.x) / T(2), this->min.y };
418 case Anchor::TopRight:
419 return { this->max.x, this->min.y };
421 return { this->min.x, (this->min.y + this->max.y) / T(2) };
422 case Anchor::Center:
423 return this->getCenter();
425 return { this->max.x, (this->min.y + this->max.y) / T(2) };
427 return { this->min.x, this->max.y };
429 return { (this->min.x + this->max.x) / T(2), this->max.y };
431 return this->max;
432 }
433
434 return this->min;
435 }
436
442 constexpr Vector<T, 2> getTopLeft() const noexcept {
443 return getPositionFromAnchor(Anchor::TopLeft);
444 }
445
451 constexpr Vector<T, 2> getTopRight() const noexcept {
452 return getPositionFromAnchor(Anchor::TopRight);
453 }
454
460 constexpr Vector<T, 2> getBottomLeft() const noexcept {
461 return getPositionFromAnchor(Anchor::BottomLeft);
462 }
463
469 constexpr Vector<T, 2> getBottomRight() const noexcept {
470 return getPositionFromAnchor(Anchor::BottomRight);
471 }
472
478 constexpr T getWidth() const noexcept {
479 return this->max.x - this->min.x;
480 }
481
487 constexpr T getHeight() const noexcept {
488 return this->max.y - this->min.y;
489 }
490
493
494 private:
495 constexpr Rect(Vector<T, 2> min, Vector<T, 2> max) noexcept
496 : min(min)
497 , max(max)
498 {
499 }
500 };
501
509
517
525
533
541
542// MSVC does not like extern template
543#ifndef _MSC_VER
544 extern template struct GF_CORE_API Rect<float>;
545 extern template struct GF_CORE_API Rect<double>;
546 extern template struct GF_CORE_API Rect<int>;
547 extern template struct GF_CORE_API Rect<unsigned>;
548#endif
549
558 template<typename T>
559 inline
560 bool operator==(const Rect<T>& lhs, const Rect<T>& rhs) {
561 return lhs.min == rhs.min && lhs.max == rhs.max;
562 }
563
572 template<typename T>
573 inline
574 bool operator!=(const Rect<T>& lhs, const Rect<T>& rhs) {
575 return !(lhs == rhs);
576 }
577
585 template<typename T>
586 constexpr
587 Rect<T> computeBoxQuarter(const Rect<T>& other, Quarter quarter) {
588 Vector<T, 2> size = (other.max - other.min) / 2;
589
590 switch (quarter) {
592 return Rect<T>::fromMinMax(other.min, other.max - size);
594 return Rect<T>::fromMinMax({ other.min.x + size.width, other.min.y }, { other.max.x, other.max.y - size.height });
596 return Rect<T>::fromMinMax(other.min + size, other.max);
598 return Rect<T>::fromMinMax({ other.min.x, other.min.y + size.height }, { other.max.x - size.width, other.max.y });
599 }
600
601 return other;
602 }
603
612 template<typename Archive, typename T>
613 Archive& operator|(Archive& ar, Rect<T>& rect) {
614 return ar | rect.min.x | rect.min.y | rect.max.x | rect.max.y;
615 }
616
617
618#ifndef DOXYGEN_SHOULD_SKIP_THIS
619}
620#endif
621}
622
623#endif // GF_RECT_H
constexpr Rect< T > computeBoxQuarter(const Rect< T > &other, Quarter quarter)
Divide a rectangle in quarters.
Definition: Rect.h:587
constexpr ZeroType Zero
Constant to represent "zero".
Definition: Types.h:93
Quarter
A quarter in a square.
Definition: Quarter.h:33
@ UpperRight
Upper-right quarter.
Definition: Quarter.h:35
@ LowerLeft
Lower-left quarter.
Definition: Quarter.h:37
@ UpperLeft
Upper-left quarter.
Definition: Quarter.h:34
@ LowerRight
Lower-right quarter.
Definition: Quarter.h:36
Anchor
An anchor of a box.
Definition: Anchor.h:38
@ TopRight
Top-right.
@ Center
Center.
@ BottomRight
Bottom-right.
@ TopCenter
Top-center.
@ BottomLeft
Bottom-left.
@ CenterLeft
Center-left.
@ CenterRight
Center-right.
@ TopLeft
Top-left.
@ BottomCenter
Bottom-center.
The namespace for gf classes.
Utility class for manipulating 2D axis aligned rectangles.
Definition: Rect.h:87
constexpr Vector< T, 2 > getTopLeft() const noexcept
Get the top left corner.
Definition: Rect.h:442
constexpr Rect shrink(T value) const noexcept
Shrink the rectangle.
Definition: Rect.h:394
constexpr void extend(Vector< T, 2 > point) noexcept
Extend the rectangle with a point.
Definition: Rect.h:319
constexpr Vector< T, 2 > getCenter() const noexcept
Get the center of the rectangle.
Definition: Rect.h:187
constexpr Vector< T, 2 > getTopRight() const noexcept
Get the top right corner.
Definition: Rect.h:451
constexpr T getIntersectionVolume(const Rect &other) const noexcept
Get the volume of the intersection.
Definition: Rect.h:260
bool operator==(const Rect< T > &lhs, const Rect< T > &rhs)
Equality operator.
Definition: Rect.h:560
static constexpr Rect< T > fromSize(Vector< T, 2 > size) noexcept
Create a rectangle from a size.
Definition: Rect.h:129
constexpr bool intersects(const Rect &other, Rect &result) const noexcept
Check if two rectangles interset and get the intersetion rectangle.
Definition: Rect.h:228
static constexpr Rect< T > fromPositionSize(Vector< T, 2 > position, Vector< T, 2 > size) noexcept
Create a rectangle from a position (top-left) and a size.
Definition: Rect.h:117
Archive & operator|(Archive &ar, Rect< T > &rect)
Serialize a rectangle.
Definition: Rect.h:613
bool operator!=(const Rect< T > &lhs, const Rect< T > &rhs)
Inequality operator.
Definition: Rect.h:574
constexpr bool contains(Vector< T, 2 > point) const noexcept
Check if a point is inside the rectangle.
Definition: Rect.h:197
constexpr Vector< T, 2 > getBottomRight() const noexcept
Get the bottom right corner.
Definition: Rect.h:469
constexpr Vector< T, 2 > getPositionFromAnchor(Anchor anchor) const noexcept
Get a position from the rectangle and an anchor.
Definition: Rect.h:412
Vector< T, 2 > max
The maximum point of the rectangle.
Definition: Rect.h:492
constexpr Rect() noexcept
Default constructor.
Definition: Rect.h:93
constexpr T getVolume() const noexcept
Get the volume of the rectangle.
Definition: Rect.h:354
constexpr Rect getIntersection(const Rect &other) const noexcept
Compute the intersection of two rectangles.
Definition: Rect.h:243
constexpr T getMinimumEdge() const noexcept
Get the minimum edge of the rectangle.
Definition: Rect.h:372
constexpr bool intersects(const Rect &other) const noexcept
Check if two rectangles interset.
Definition: Rect.h:217
constexpr T getIntersectionExtentLength(const Rect &other) const noexcept
Get the extent length of the intersection.
Definition: Rect.h:284
constexpr void extend(const T(&point)[2]) noexcept
Extend the rectangle with a point (as array)
Definition: Rect.h:307
constexpr void normalize() noexcept
Ensures that min coordinates are less than max coordinates.
Definition: Rect.h:401
static constexpr Rect< T > fromMinMax(Vector< T, 2 > min, Vector< T, 2 > max) noexcept
Create a rectangle from a min point and a max point.
Definition: Rect.h:106
constexpr T getExtentLength() const noexcept
Get the extent length of the rectangle.
Definition: Rect.h:363
constexpr T getHeight() const noexcept
Get the height of the rectangle.
Definition: Rect.h:487
static constexpr Rect< T > fromCenterSize(Vector< T, 2 > center, Vector< T, 2 > size) noexcept
Create a rectangle from a center and a size.
Definition: Rect.h:140
constexpr bool contains(const Rect &other) const noexcept
Check if a rectangle is totally inside the rectangle.
Definition: Rect.h:207
constexpr Rect grow(T value) const noexcept
Grow the rectangle.
Definition: Rect.h:383
constexpr Vector< T, 2 > getBottomLeft() const noexcept
Get the bottom left corner.
Definition: Rect.h:460
constexpr bool isEmpty() const noexcept
Check if the rectangle is empty.
Definition: Rect.h:178
constexpr Rect getExtended(const Rect &other) const noexcept
Get the rectangle extended by another rectangle.
Definition: Rect.h:343
Vector< T, 2 > min
The minimum point of the rectangle.
Definition: Rect.h:491
constexpr T getWidth() const noexcept
Get the width of the rectangle.
Definition: Rect.h:478
static constexpr Rect< T > empty() noexcept
Create an empty rectangle.
Definition: Rect.h:149
constexpr Vector< T, 2 > getPosition() const noexcept
Get the position of the rectangle.
Definition: Rect.h:160
constexpr Vector< T, 2 > getSize() const noexcept
Get the size of the rectangle.
Definition: Rect.h:169
constexpr void extend(const Rect &other) noexcept
Extend the rectangle with a rectangle.
Definition: Rect.h:331
A 2D vector.
Definition: Vector.h:316
T height
Second coordinate in the size representation.
Definition: Vector.h:528
T width
First coordinate in the size representation.
Definition: Vector.h:517
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:525
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:514