You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.2 KiB
78 lines
2.2 KiB
#pragma once |
|
|
|
#include "engine/point.hpp" |
|
#include "engine/size.hpp" |
|
|
|
namespace devilution { |
|
|
|
template <typename CoordT, typename SizeT = CoordT> |
|
struct RectangleOf { |
|
PointOf<CoordT> position; |
|
SizeOf<SizeT> size; |
|
|
|
RectangleOf() = default; |
|
|
|
constexpr RectangleOf(PointOf<CoordT> position, SizeOf<SizeT> size) |
|
: position(position) |
|
, size(size) |
|
{ |
|
} |
|
|
|
/** |
|
* @brief Constructs a rectangle centered on the given point and including all tiles within the given radius. |
|
* |
|
* The resulting rectangle will be square with an odd size equal to 2*radius + 1. |
|
* |
|
* @param center center point of the target rectangle |
|
* @param radius a non-negative value indicating how many tiles to include around the center |
|
*/ |
|
explicit constexpr RectangleOf(PointOf<CoordT> center, SizeT radius) |
|
: position(center - DisplacementOf<SizeT> { radius }) |
|
, size(static_cast<SizeT>(2 * radius + 1)) |
|
{ |
|
} |
|
|
|
/** |
|
* @brief Whether this rectangle contains the given point. |
|
* Works correctly even if the point uses a different underlying numeric type |
|
*/ |
|
template <typename PointCoordT> |
|
constexpr bool contains(PointOf<PointCoordT> point) const |
|
{ |
|
return contains(point.x, point.y); |
|
} |
|
|
|
template <typename T> |
|
constexpr bool contains(T x, T y) const |
|
{ |
|
return x >= this->position.x |
|
&& x < (this->position.x + this->size.width) |
|
&& y >= this->position.y |
|
&& y < (this->position.y + this->size.height); |
|
} |
|
|
|
/** |
|
* @brief Computes the center of this rectangle in integer coordinates. Values are truncated towards zero. |
|
*/ |
|
constexpr PointOf<CoordT> Center() const |
|
{ |
|
return position + DisplacementOf<SizeT>(size / 2); |
|
} |
|
|
|
/** |
|
* @brief Returns a rectangle with all sides shrunk according to the given displacement |
|
* |
|
* Effectively moves the left/right edges in by deltaX, and the top/bottom edges in by deltaY |
|
*/ |
|
constexpr RectangleOf<CoordT, SizeT> inset(DisplacementOf<SizeT> factor) const |
|
{ |
|
return { |
|
position + factor, |
|
SizeOf<SizeT>(size.width - factor.deltaX * 2, size.height - factor.deltaY * 2) |
|
}; |
|
} |
|
}; |
|
|
|
using Rectangle = RectangleOf<int, int>; |
|
|
|
} // namespace devilution
|
|
|