7#include "../rapid/numeric_array.hpp"
9#include "../concepts.hpp"
10#include "../unfair_mutex.hpp"
16namespace hi::inline v1 {
38 hi_axiom(holds_invariant());
48 constexpr axis_aligned_rectangle(
float x,
float y,
float width,
float height) noexcept : v{x, y, x + width, y + height}
50 hi_axiom(holds_invariant());
59 hi_axiom(holds_invariant());
67 v(
static_cast<f32x4>(p0).xy00() +
static_cast<f32x4>(p3)._00xy())
69 hi_axiom(p0.holds_invariant());
70 hi_axiom(p3.holds_invariant());
71 hi_axiom(holds_invariant());
79 v(
static_cast<f32x4>(p0).xyxy() +
static_cast<f32x4>(extent)._00xy())
81 hi_axiom(holds_invariant());
84 constexpr explicit operator f32x4() const noexcept
94 return le(v, v.zwzw()) == 0b1111;
99 [[nodiscard]]
constexpr bool empty() const noexcept
101 return eq(v, v.zwxy()) == 0b1111;
106 [[nodiscard]]
constexpr explicit operator bool() const noexcept
118 return *
this = *
this | rhs;
128 return *
this = *
this | rhs;
134 case 0:
return point2{v.xy01()};
135 case 1:
return point2{v.zy01()};
136 case 2:
return point2{v.xw01()};
137 case 3:
return point2{v.zw01()};
138 default: hi_no_default();
143 [[nodiscard]]
constexpr friend point2 get(axis_aligned_rectangle
const &rhs)
noexcept
145 if constexpr (I == 0) {
146 return point2{rhs.v.xy01()};
147 }
else if constexpr (I == 1) {
148 return point2{rhs.v.zy01()};
149 }
else if constexpr (I == 2) {
150 return point2{rhs.v.xw01()};
151 }
else if constexpr (I == 3) {
152 return point2{rhs.v.zw01()};
154 hi_static_no_default();
167 [[nodiscard]]
constexpr float width() const noexcept
169 return (v.zwzw() - v).x();
172 [[nodiscard]]
constexpr float height() const noexcept
174 return (v.zwzw() - v).y();
177 [[nodiscard]]
constexpr float bottom() const noexcept
182 [[nodiscard]]
constexpr float top() const noexcept
187 [[nodiscard]]
constexpr float left() const noexcept
192 [[nodiscard]]
constexpr float right() const noexcept
199 [[nodiscard]]
constexpr float middle() const noexcept
206 [[nodiscard]]
constexpr float center() const noexcept
208 return (left() + right()) * 0.5f;
215 return midpoint(get<0>(rhs), get<3>(rhs));
221 v = v.xyxw() +
f32x4{0.0f, 0.0f, newWidth, 0.0f};
225 constexpr axis_aligned_rectangle &set_height(
float newHeight)
noexcept
227 v = v.xyzy() + f32x4{0.0f, 0.0f, 0.0f, newHeight};
238 return ge(
static_cast<f32x4>(rhs).xyxy(), v) == 0b0011;
248 return contains(
point2{rhs});
261 if (
alignment == horizontal_alignment::left) {
264 }
else if (
alignment == horizontal_alignment::right) {
265 x = haystack.right() - needle.width();
267 }
else if (
alignment == horizontal_alignment::center) {
268 x = haystack.center() - needle.width() * 0.5f;
275 if (
alignment == vertical_alignment::bottom) {
276 y = haystack.bottom();
278 }
else if (
alignment == vertical_alignment::top) {
279 y = haystack.top() - needle.height();
281 }
else if (
alignment == vertical_alignment::middle) {
282 y = haystack.middle() - needle.height() * 0.5f;
288 return {
point2{x, y}, needle};
300 return align(haystack, needle.size(),
alignment);
308 return align(outside, inside,
alignment);
313 return lhs.v == rhs.v;
316 [[nodiscard]]
friend constexpr bool overlaps(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
318 if (lhs.empty() or rhs.
empty()) {
322 hilet rhs_swap = rhs.v.zwxy();
325 if ((gt(lhs.v, rhs_swap) & 0b0011) != 0) {
330 if ((lt(lhs.v, rhs_swap) & 0b1100) != 0) {
337 [[nodiscard]]
friend constexpr axis_aligned_rectangle
338 operator|(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
345 return axis_aligned_rectangle{
min(get<0>(lhs), get<0>(rhs)),
max(get<3>(lhs), get<3>(rhs))};
349 [[nodiscard]]
friend constexpr axis_aligned_rectangle
operator|(axis_aligned_rectangle
const &lhs, point2
const &rhs)
noexcept
352 return axis_aligned_rectangle{rhs, rhs};
354 return axis_aligned_rectangle{
min(get<0>(lhs), rhs),
max(get<3>(lhs), rhs)};
368 hilet offset = diff * 0.5f;
370 hilet p0 = get<0>(lhs) - offset;
371 hilet p3 = max(get<3>(lhs) + offset, p0);
399 hilet p0 = round(get<0>(rhs));
408 hilet p0 = floor(get<0>(rhs));
409 hilet p3 = ceil(get<3>(rhs));
417 hilet p0 = floor(get<0>(lhs), rhs);
418 hilet p3 = ceil(get<3>(lhs), rhs);
426 hilet p0 = ceil(get<0>(rhs));
427 hilet p3 = floor(get<3>(rhs));
439 [[nodiscard]]
friend constexpr axis_aligned_rectangle
442 hilet p0 = max(get<0>(lhs), get<0>(rhs));
443 hilet p3 = min(get<3>(lhs), get<3>(rhs));
444 if (p0.x() < p3.x() && p0.y() < p3.y()) {
466 hilet closest_point = max(min(rhs_, lhs_.zwzw()), lhs_);
467 hilet v_closest_point = closest_point - rhs_;
468 return hypot<0b0011>(v_closest_point);
472using aarectangle = axis_aligned_rectangle;
479 static constexpr bool is_always_lock_free =
false;
481 constexpr atomic()
noexcept =
default;
487 constexpr atomic(hi::axis_aligned_rectangle
const &rhs) noexcept : _value(rhs) {}
494 operator hi::axis_aligned_rectangle()
const noexcept
501 return is_always_lock_free;
504 void store(hi::axis_aligned_rectangle desired, std::memory_order = std::memory_order_seq_cst)
noexcept
510 hi::axis_aligned_rectangle
load(std::memory_order = std::memory_order_seq_cst)
const noexcept
516 hi::axis_aligned_rectangle
517 exchange(hi::axis_aligned_rectangle desired, std::memory_order = std::memory_order_seq_cst)
noexcept
520 return std::exchange(_value, desired);
524 hi::axis_aligned_rectangle &expected,
525 hi::axis_aligned_rectangle desired,
527 std::memory_order)
noexcept
530 if (_value == expected) {
540 hi::axis_aligned_rectangle &expected,
541 hi::axis_aligned_rectangle desired,
542 std::memory_order success,
543 std::memory_order failure)
noexcept
549 hi::axis_aligned_rectangle &expected,
550 hi::axis_aligned_rectangle desired,
551 std::memory_order order = std::memory_order_seq_cst)
noexcept
557 hi::axis_aligned_rectangle &expected,
558 hi::axis_aligned_rectangle desired,
559 std::memory_order order = std::memory_order_seq_cst)
noexcept
564 hi::axis_aligned_rectangle
fetch_or(hi::axis_aligned_rectangle arg, std::memory_order = std::memory_order_seq_cst)
noexcept
572 hi::axis_aligned_rectangle
operator|=(hi::axis_aligned_rectangle arg)
noexcept
575 return _value |= arg;
579 hi::axis_aligned_rectangle _value;
580 mutable hi::unfair_mutex _mutex;
583template<
typename CharT>
584struct std::formatter<hi::axis_aligned_rectangle, CharT> : std::formatter<float, CharT> {
590 auto format(hi::axis_aligned_rectangle
const &t,
auto &fc)
592 return std::vformat_to(fc.out(),
"{}:{}", std::make_format_args(get<0>(t), t.size()));
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
constexpr alignment operator|(horizontal_alignment lhs, vertical_alignment rhs) noexcept
Combine vertical and horizontal alignment.
Definition alignment.hpp:200
@ bottom
Align to the bottom.
Definition alignment.hpp:64
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
friend constexpr axis_aligned_rectangle floor(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by shrinking to pixel edge.
Definition axis_aligned_rectangle.hpp:424
friend axis_aligned_rectangle fit(axis_aligned_rectangle const &bounds, axis_aligned_rectangle const &rectangle) noexcept
Make a rectangle fit inside bounds.
constexpr float center() const noexcept
The center on the x-axis between left and right.
Definition axis_aligned_rectangle.hpp:206
friend constexpr 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:440
friend constexpr axis_aligned_rectangle operator*(axis_aligned_rectangle const &lhs, float rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:364
constexpr bool empty() const noexcept
Check if the rectangle has no area.
Definition axis_aligned_rectangle.hpp:99
static constexpr axis_aligned_rectangle _align(axis_aligned_rectangle outside, axis_aligned_rectangle inside, alignment alignment) noexcept
Need to call the hidden friend function from within another class.
Definition axis_aligned_rectangle.hpp:306
friend constexpr 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:298
friend constexpr axis_aligned_rectangle ceil(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by expanding to pixel edge.
Definition axis_aligned_rectangle.hpp:406
constexpr axis_aligned_rectangle & operator|=(axis_aligned_rectangle const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:116
friend constexpr axis_aligned_rectangle operator-(axis_aligned_rectangle const &lhs, float rhs) noexcept
Shrink the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:392
constexpr 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
constexpr 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
constexpr bool holds_invariant() const noexcept
Make sure p0 is left/bottom from p3.
Definition axis_aligned_rectangle.hpp:92
constexpr axis_aligned_rectangle & operator|=(point2 const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:126
constexpr extent2 size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:162
friend constexpr axis_aligned_rectangle ceil(axis_aligned_rectangle const &lhs, extent2 const &rhs) noexcept
Round rectangle by expanding to a certain granularity.
Definition axis_aligned_rectangle.hpp:415
constexpr bool contains(point2 const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:235
friend constexpr axis_aligned_rectangle operator+(axis_aligned_rectangle const &lhs, float rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:381
constexpr bool contains(point3 const &rhs) const noexcept
Check if a 3D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:246
constexpr float middle() const noexcept
The middle on the y-axis between bottom and top.
Definition axis_aligned_rectangle.hpp:199
constexpr axis_aligned_rectangle(extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:57
constexpr friend point2 midpoint(axis_aligned_rectangle const &rhs) noexcept
Get the center of the rectangle.
Definition axis_aligned_rectangle.hpp:213
friend constexpr axis_aligned_rectangle align(axis_aligned_rectangle haystack, extent2 needle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition axis_aligned_rectangle.hpp:258
constexpr axis_aligned_rectangle(point2 const &p0, extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:78
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
T compare_exchange_weak(T... args)
T is_lock_free(T... args)