7#include "numeric_array.hpp"
8#include "../alignment.hpp"
9#include "../concepts.hpp"
67 v(
static_cast<f32x4>(p0).xy00() +
static_cast<f32x4>(p3)._00xy())
69 tt_axiom(p0.is_valid());
70 tt_axiom(p3.is_valid());
89 return le(v, v.zwzw()) == 0b1111;
94 [[nodiscard]]
bool empty() const noexcept
96 return eq(v, v.zwxy()) == 0b1111;
101 [[nodiscard]]
operator bool() const noexcept
113 return *
this = *
this | rhs;
123 return *
this = *
this | rhs;
126 [[nodiscard]]
constexpr point2 operator[](
size_t i)
const noexcept
129 case 0:
return point2{v.xy01()};
130 case 1:
return point2{v.zy01()};
131 case 2:
return point2{v.xw01()};
132 case 3:
return point2{v.zw01()};
133 default: tt_no_default();
138 [[nodiscard]]
constexpr friend point2 get(axis_aligned_rectangle
const &rhs)
noexcept
140 if constexpr (I == 0) {
141 return point2{rhs.v.xy01()};
142 }
else if constexpr (I == 1) {
143 return point2{rhs.v.zy01()};
144 }
else if constexpr (I == 2) {
145 return point2{rhs.v.xw01()};
146 }
else if constexpr (I == 3) {
147 return point2{rhs.v.zw01()};
149 tt_static_no_default();
162 [[nodiscard]]
float width() const noexcept
164 return (v.zwzw() - v).x();
167 [[nodiscard]]
float height() const noexcept
169 return (v.zwzw() - v).y();
172 [[nodiscard]]
float bottom() const noexcept
177 [[nodiscard]]
float top() const noexcept
182 [[nodiscard]]
float left() const noexcept
187 [[nodiscard]]
float right() const noexcept
194 [[nodiscard]]
float middle() const noexcept
196 return (bottom() + top()) * 0.5f;
201 [[nodiscard]]
float center() const noexcept
203 return (left() + right()) * 0.5f;
208 v = v.xyxw() +
f32x4{0.0f, 0.0f, newWidth, 0.0f};
212 axis_aligned_rectangle &set_height(
float newHeight)
noexcept
214 v = v.xyzy() + f32x4{0.0f, 0.0f, 0.0f, newHeight};
225 return ge(
static_cast<f32x4>(rhs).xyxy(), v) == 0b0011;
238 if (alignment == horizontal_alignment::left) {
241 }
else if (alignment == horizontal_alignment::right) {
242 x = haystack.right() - needle.width();
244 }
else if (alignment == horizontal_alignment::center) {
245 x = haystack.center() - needle.width() * 0.5f;
252 if (alignment == vertical_alignment::bottom) {
253 y = haystack.bottom();
255 }
else if (alignment == vertical_alignment::top) {
256 y = haystack.top() - needle.height();
258 }
else if (alignment == vertical_alignment::middle) {
259 y = haystack.middle() - needle.height() * 0.5f;
265 return {
point2{x, y}, needle.extent()};
273 return align(outside, inside, alignment);
278 return lhs.v == rhs.v;
281 [[nodiscard]]
friend bool operator!=(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
283 return !(lhs == rhs);
286 [[nodiscard]]
friend bool overlaps(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
288 if (lhs.empty() || rhs.
empty()) {
292 ttlet rhs_swap = rhs.v.zwxy();
295 if ((gt(lhs.v, rhs_swap) & 0b0011) != 0) {
300 if ((lt(lhs.v, rhs_swap) & 0b1100) != 0) {
307 [[nodiscard]]
friend axis_aligned_rectangle
308 operator|(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
315 return axis_aligned_rectangle{
min(get<0>(lhs), get<0>(rhs)),
max(get<3>(lhs), get<3>(rhs))};
319 [[nodiscard]]
friend axis_aligned_rectangle operator|(axis_aligned_rectangle
const &lhs, point2
const &rhs)
noexcept
322 return axis_aligned_rectangle{rhs, rhs};
324 return axis_aligned_rectangle{
min(get<0>(lhs), rhs),
max(get<3>(lhs), rhs)};
332 return get<0>(rhs) + (get<3>(rhs) - get<0>(rhs)) * 0.5f;
342 ttlet
extent = lhs.extent();
343 ttlet scaled_extent =
extent * rhs;
344 ttlet diff_extent = scaled_extent -
extent;
345 ttlet half_diff_extent = diff_extent * 0.5f;
347 ttlet p1 = get<0>(lhs) -
vector2{half_diff_extent};
348 ttlet p2 = get<3>(lhs) +
vector2{half_diff_extent};
376 auto p0 = round(get<0>(rhs));
377 auto p3 = round(get<3>(rhs));
385 auto p0 =
floor(get<0>(rhs));
386 auto p3 =
ceil(get<3>(rhs));
394 auto p0 =
ceil(get<0>(rhs));
395 auto p3 =
floor(get<3>(rhs));
405 ttlet p0 = max(get<0>(lhs), get<0>(rhs));
406 ttlet p3 = min(get<3>(lhs), get<3>(rhs));
407 if (p0.x() < p3.x() && p0.y() < p3.y()) {
Definition sfloat_rgba32.hpp:15
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:18
friend axis_aligned_rectangle shrink(axis_aligned_rectangle const &lhs, float rhs) noexcept
Shrink the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:369
axis_aligned_rectangle & operator|=(axis_aligned_rectangle const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:111
bool contains(point2 const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:222
extent2 extent() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:157
static axis_aligned_rectangle _align(axis_aligned_rectangle outside, axis_aligned_rectangle inside, alignment alignment) noexcept
Need to call the hiden friend function from within another class.
Definition axis_aligned_rectangle.hpp:271
friend axis_aligned_rectangle ceil(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by expanding to pixel edge.
Definition axis_aligned_rectangle.hpp:383
friend point2 center(axis_aligned_rectangle const &rhs) noexcept
Get the center of the rectangle.
Definition axis_aligned_rectangle.hpp:330
float middle() const noexcept
The middle on the y-axis between bottom and top.
Definition axis_aligned_rectangle.hpp:194
axis_aligned_rectangle(point2 const &p0, extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:78
axis_aligned_rectangle(point2 const &p0, point2 const &p3) noexcept
Create a rectangle from the left-bottom and right-top points.
Definition axis_aligned_rectangle.hpp:66
friend axis_aligned_rectangle fit(axis_aligned_rectangle const &bounds, axis_aligned_rectangle const &rectangle) noexcept
Make a rectangle fit inside bounds.
friend axis_aligned_rectangle scale(axis_aligned_rectangle const &lhs, float rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:340
friend axis_aligned_rectangle floor(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by shrinking to pixel edge.
Definition axis_aligned_rectangle.hpp:392
axis_aligned_rectangle(float x, float y, float width, float height) noexcept
Create a box from the position and size.
Definition axis_aligned_rectangle.hpp:48
friend axis_aligned_rectangle align(axis_aligned_rectangle haystack, axis_aligned_rectangle needle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition axis_aligned_rectangle.hpp:235
friend axis_aligned_rectangle expand(axis_aligned_rectangle const &lhs, float rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:358
axis_aligned_rectangle & operator|=(point2 const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:121
bool is_valid() const noexcept
Make sure p0 is left/bottom from p3.
Definition axis_aligned_rectangle.hpp:87
bool empty() const noexcept
Check if the rectangle has no area.
Definition axis_aligned_rectangle.hpp:94
axis_aligned_rectangle(extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:57
friend axis_aligned_rectangle intersect(axis_aligned_rectangle const &lhs, axis_aligned_rectangle const &rhs) noexcept
Return the overlapping part of two rectangles.
Definition axis_aligned_rectangle.hpp:403
float center() const noexcept
The center on the x-axis between left and right.
Definition axis_aligned_rectangle.hpp:201
Class which represents an rectangle.
Definition rectangle.hpp:16