Gamedev Framework (gf)  0.12.0
A C++14 framework for 2D games
Rect.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 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 
30 #include "Anchor.h"
31 #include "Portability.h"
32 #include "Vector.h"
33 
34 namespace gf {
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 inline namespace v1 {
37 #endif
38 
87  template<typename T>
88  struct Rect {
89  T left;
90  T top;
91  T width;
93 
100  constexpr Rect() noexcept
101  : left{0}, top{0}, width{0}, height{0}
102  {
103 
104  }
105 
117  constexpr Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) noexcept
118  : left{rectLeft}, top{rectTop}, width{rectWidth}, height{rectHeight}
119  {
120 
121  }
122 
132  constexpr Rect(Vector<T, 2> position, Vector<T, 2> size) noexcept
133  : left(position.x), top(position.y), width(size.x), height(size.y)
134  {
135 
136  }
137 
141  Rect(const Rect&) = default;
142 
146  Rect& operator=(const Rect&) = default;
147 
154  constexpr Vector<T, 2> getPosition() const noexcept {
155  return { left, top };
156  }
157 
164  constexpr void setPosition(Vector<T, 2> position) noexcept {
165  left = position.x;
166  top = position.y;
167  }
168 
175  constexpr Vector<T, 2> getSize() const noexcept {
176  return { width, height };
177  }
178 
185  constexpr void setSize(Vector<T, 2> size) noexcept {
186  width = size.width;
187  height = size.height;
188  }
189 
198  constexpr bool isEmpty() const noexcept {
199  return width == 0 || height == 0;
200  }
201 
202  constexpr Vector<T, 2> getPositionFromAnchor(Anchor anchor) const noexcept {
203  switch (anchor) {
204  case Anchor::TopLeft:
205  return { left, top };
206  case Anchor::TopCenter:
207  return { left + width / 2, top };
208  case Anchor::TopRight:
209  return { left + width, top };
210  case Anchor::CenterLeft:
211  return { left, top + height / 2 };
212  case Anchor::Center:
213  return { left + width / 2, top + height / 2 };
214  case Anchor::CenterRight:
215  return { left + width, top + height / 2 };
216  case Anchor::BottomLeft:
217  return { left, top + height };
219  return { left + width / 2, top + height };
220  case Anchor::BottomRight:
221  return { left + width, top + height };
222  }
223 
224  return { left, top };
225  }
226 
232  constexpr Vector<T, 2> getCenter() const noexcept {
233  return getPositionFromAnchor(Anchor::Center);
234  }
235 
241  constexpr Vector<T, 2> getTopLeft() const noexcept {
242  return getPositionFromAnchor(Anchor::TopLeft);
243  }
244 
250  constexpr Vector<T, 2> getTopRight() const noexcept {
251  return getPositionFromAnchor(Anchor::TopRight);
252  }
253 
259  constexpr Vector<T, 2> getBottomLeft() const noexcept {
260  return getPositionFromAnchor(Anchor::BottomLeft);
261  }
262 
268  constexpr Vector<T, 2> getBottomRight() const noexcept {
269  return getPositionFromAnchor(Anchor::BottomRight);
270  }
271 
272 
280  constexpr bool contains(const Vector<T, 2>& point) const noexcept {
281  return left <= point.x && point.x < left + width && top <= point.y && point.y < top + height;
282  }
283 
291  constexpr bool contains(const Rect<T>& other) const noexcept {
292  return left <= other.left && other.left + other.width <= left + width
293  && top <= other.top && other.top + other.height <= top + height;
294  }
295 
303  constexpr bool intersects(const Rect<T>& other) const noexcept {
304  return left + width > other.left && left < other.left + other.width
305  && top + height > other.top && top < other.top + other.height;
306  }
307 
319  bool intersects(const Rect<T>& other, Rect<T>& result) const noexcept {
320  if (!intersects(other)) {
321  result = Rect<T>();
322  return false;
323  }
324 
325  T resultLeft = std::max(left, other.left);
326  T resultTop = std::max(top, other.top);
327  T resultRight = std::min(left + width, other.left + other.width);
328  T resultBottom = std::min(top + height, other.top + other.height);
329 
330  result = Rect<T>(resultLeft, resultTop, resultRight - resultLeft, resultBottom - resultTop);
331  return true;
332  }
333 
341  constexpr Rect<T> grow(T value) const noexcept {
342  return Rect<T>(left - value, top - value, width + 2 * value, height + 2 * value);
343  }
344 
352  constexpr Rect<T> shrink(T value) const noexcept {
353  return Rect<T>(left + value, top + value, width - 2 * value, height - 2 * value);
354  }
355  };
356 
364 
372 
379  using RectI = Rect<int>;
380 
388 
396 
397 // MSVC does not like extern template
398 #ifndef _MSC_VER
399  extern template struct GF_API Rect<float>;
400  extern template struct GF_API Rect<double>;
401  extern template struct GF_API Rect<int>;
402  extern template struct GF_API Rect<unsigned>;
403 #endif
404 
413  template<typename T>
414  inline
415  bool operator==(const Rect<T>& lhs, const Rect<T>& rhs) {
416  return lhs.left == rhs.left && lhs.top == rhs.top && lhs.width == rhs.width && lhs.height == rhs.height;
417  }
418 
427  template<typename T>
428  inline
429  bool operator!=(const Rect<T>& lhs, const Rect<T>& rhs) {
430  return !(lhs == rhs);
431  }
432 
441  template<typename Archive, typename T>
442  Archive& operator|(Archive& ar, Rect<T>& rect) {
443  return ar | rect.left | rect.top | rect.width | rect.height;
444  }
445 
446 
447 #ifndef DOXYGEN_SHOULD_SKIP_THIS
448 }
449 #endif
450 }
451 
452 #endif // GF_RECT_H
T top
Top coordinate of the rectangle.
Definition: Rect.h:90
constexpr Vector< T, 2 > getBottomLeft() const noexcept
Get the bottom left corner.
Definition: Rect.h:259
bool operator!=(const Rect< T > &lhs, const Rect< T > &rhs)
Inequality operator.
Definition: Rect.h:429
constexpr bool isEmpty() const noexcept
Check if the rectangle is empty.
Definition: Rect.h:198
constexpr Vector< T, 2 > getPositionFromAnchor(Anchor anchor) const noexcept
Definition: Rect.h:202
Archive & operator|(Archive &ar, Rect< T > &rect)
Serialize a rectangle.
Definition: Rect.h:442
bool intersects(const Rect< T > &other, Rect< T > &result) const noexcept
Check the intersection between two rectangles.
Definition: Rect.h:319
constexpr Vector< T, 2 > getPosition() const noexcept
Get the position of the rectangle.
Definition: Rect.h:154
constexpr Rect< T > grow(T value) const noexcept
Grow the rectangle.
Definition: Rect.h:341
constexpr void setPosition(Vector< T, 2 > position) noexcept
Set the position of the rectangle.
Definition: Rect.h:164
constexpr bool intersects(const Rect< T > &other) const noexcept
Check the intersection between two rectangles.
Definition: Rect.h:303
constexpr void setSize(Vector< T, 2 > size) noexcept
Set the size of the rectangle.
Definition: Rect.h:185
constexpr bool contains(const Rect< T > &other) const noexcept
Check if a rectangle is inside the rectangle&#39;s area.
Definition: Rect.h:291
constexpr Vector< T, 2 > getTopRight() const noexcept
Get the top right corner.
Definition: Rect.h:250
T width
Width of the rectangle.
Definition: Rect.h:91
Utility class for manipulating 2D axis aligned rectangles.
Definition: Rect.h:88
The namespace for gf classes.
Definition: Action.h:35
constexpr Rect< T > shrink(T value) const noexcept
Shrink the rectangle.
Definition: Rect.h:352
constexpr Vector< T, 2 > getCenter() const noexcept
Get the center of the rectangle.
Definition: Rect.h:232
constexpr Rect(Vector< T, 2 > position, Vector< T, 2 > size) noexcept
Construct the rectangle from position and size.
Definition: Rect.h:132
A 2D vector.
Definition: Vector.h:316
constexpr Rect() noexcept
Default constructor.
Definition: Rect.h:100
constexpr Vector< T, 2 > getTopLeft() const noexcept
Get the top left corner.
Definition: Rect.h:241
T left
Left coordinate of the rectangle.
Definition: Rect.h:89
T height
Height of the rectangle.
Definition: Rect.h:92
constexpr Vector< T, 2 > getBottomRight() const noexcept
Get the bottom right corner.
Definition: Rect.h:268
Anchor
An anchor of a box.
Definition: Anchor.h:38
constexpr bool contains(const Vector< T, 2 > &point) const noexcept
Check if a point is inside the rectangle&#39;s area.
Definition: Rect.h:280
constexpr Vector< T, 2 > getSize() const noexcept
Get the size of the rectangle.
Definition: Rect.h:175
constexpr Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) noexcept
Construct the rectangle from its coordinates.
Definition: Rect.h:117
bool operator==(const Rect< T > &lhs, const Rect< T > &rhs)
Equality operator.
Definition: Rect.h:415