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());
82 v(
static_cast<f32x4>(p0).xyxy() +
static_cast<f32x4>(extent)._00xy())
84 hi_axiom(holds_invariant());
87 constexpr explicit operator f32x4() const noexcept
97 return le(v, v.zwzw()) == 0b1111;
102 [[nodiscard]]
constexpr bool empty() const noexcept
104 return eq(v, v.zwxy()) == 0b1111;
109 [[nodiscard]]
constexpr explicit operator bool() const noexcept
121 return *
this = *
this | rhs;
131 return *
this = *
this | rhs;
140 return point2{v.zy01()};
142 return point2{v.xw01()};
144 return point2{v.zw01()};
151 [[nodiscard]]
constexpr friend point2 get(axis_aligned_rectangle
const& rhs)
noexcept
153 if constexpr (I == 0) {
154 return point2{rhs.v.xy01()};
155 }
else if constexpr (I == 1) {
156 return point2{rhs.v.zy01()};
157 }
else if constexpr (I == 2) {
158 return point2{rhs.v.xw01()};
159 }
else if constexpr (I == 3) {
160 return point2{rhs.v.zw01()};
162 hi_static_no_default();
175 [[nodiscard]]
constexpr float width() const noexcept
177 return (v.zwzw() - v).x();
180 [[nodiscard]]
constexpr float height() const noexcept
182 return (v.zwzw() - v).y();
185 [[nodiscard]]
constexpr float bottom() const noexcept
190 [[nodiscard]]
constexpr float top() const noexcept
195 [[nodiscard]]
constexpr float left() const noexcept
200 [[nodiscard]]
constexpr float right() const noexcept
207 [[nodiscard]]
constexpr float middle() const noexcept
214 [[nodiscard]]
constexpr float center() const noexcept
216 return (left() + right()) * 0.5f;
223 return midpoint(get<0>(rhs), get<3>(rhs));
228 v = v.xyxw() +
f32x4{0.0f, 0.0f, newWidth, 0.0f};
232 constexpr axis_aligned_rectangle& set_height(
float newHeight)
noexcept
234 v = v.xyzy() + f32x4{0.0f, 0.0f, 0.0f, newHeight};
245 return ge(
static_cast<f32x4>(rhs).xyxy(), v) == 0b0011;
255 return contains(
point2{rhs});
268 if (
alignment == horizontal_alignment::left) {
271 }
else if (
alignment == horizontal_alignment::right) {
272 x = haystack.right() - needle.width();
274 }
else if (
alignment == horizontal_alignment::center) {
275 x = haystack.center() - needle.width() * 0.5f;
282 if (
alignment == vertical_alignment::bottom) {
283 y = haystack.bottom();
285 }
else if (
alignment == vertical_alignment::top) {
286 y = haystack.top() - needle.height();
288 }
else if (
alignment == vertical_alignment::middle) {
289 y = haystack.middle() - needle.height() * 0.5f;
295 return {
point2{x, y}, needle};
307 return align(haystack, needle.size(),
alignment);
320 return lhs.v == rhs.v;
323 [[nodiscard]]
friend constexpr bool overlaps(axis_aligned_rectangle
const& lhs, axis_aligned_rectangle
const& rhs)
noexcept
325 if (lhs.empty() or rhs.
empty()) {
329 hilet rhs_swap = rhs.v.zwxy();
332 if ((gt(lhs.v, rhs_swap) & 0b0011) != 0) {
337 if ((lt(lhs.v, rhs_swap) & 0b1100) != 0) {
344 [[nodiscard]]
friend constexpr axis_aligned_rectangle
345 operator|(axis_aligned_rectangle
const& lhs, axis_aligned_rectangle
const& rhs)
noexcept
352 return axis_aligned_rectangle{
min(get<0>(lhs), get<0>(rhs)),
max(get<3>(lhs), get<3>(rhs))};
356 [[nodiscard]]
friend constexpr axis_aligned_rectangle
operator|(axis_aligned_rectangle
const& lhs, point2
const& rhs)
noexcept
359 return axis_aligned_rectangle{rhs, rhs};
361 return axis_aligned_rectangle{
min(get<0>(lhs), rhs),
max(get<3>(lhs), rhs)};
374 hilet offset = diff * 0.5f;
376 hilet p0 = get<0>(lhs) - offset;
377 hilet p3 = max(get<3>(lhs) + offset, p0);
405 hilet p0 = round(get<0>(rhs));
414 hilet p0 = floor(get<0>(rhs));
415 hilet p3 = ceil(get<3>(rhs));
423 hilet p0 = floor(get<0>(lhs), rhs);
424 hilet p3 = ceil(get<3>(lhs), rhs);
432 hilet p0 = ceil(get<0>(rhs));
433 hilet p3 = floor(get<3>(rhs));
445 [[nodiscard]]
friend constexpr axis_aligned_rectangle
448 hilet p0 = max(get<0>(lhs), get<0>(rhs));
449 hilet p3 = min(get<3>(lhs), get<3>(rhs));
450 if (p0.x() < p3.x() && p0.y() < p3.y()) {
471 hilet closest_point = max(min(rhs_, lhs_.zwzw()), lhs_);
472 hilet v_closest_point = closest_point - rhs_;
473 return hypot<0b0011>(v_closest_point);
477using aarectangle = axis_aligned_rectangle;
484 static constexpr bool is_always_lock_free =
false;
486 constexpr atomic()
noexcept =
default;
492 constexpr atomic(hi::axis_aligned_rectangle
const& rhs) noexcept : _value(rhs) {}
499 operator hi::axis_aligned_rectangle()
const noexcept
506 return is_always_lock_free;
509 void store(hi::axis_aligned_rectangle desired, std::memory_order = std::memory_order_seq_cst)
noexcept
515 hi::axis_aligned_rectangle
load(std::memory_order = std::memory_order_seq_cst)
const noexcept
521 hi::axis_aligned_rectangle
522 exchange(hi::axis_aligned_rectangle desired, std::memory_order = std::memory_order_seq_cst)
noexcept
525 return std::exchange(_value, desired);
529 hi::axis_aligned_rectangle& expected,
530 hi::axis_aligned_rectangle desired,
532 std::memory_order)
noexcept
535 if (_value == expected) {
545 hi::axis_aligned_rectangle& expected,
546 hi::axis_aligned_rectangle desired,
547 std::memory_order success,
548 std::memory_order failure)
noexcept
554 hi::axis_aligned_rectangle& expected,
555 hi::axis_aligned_rectangle desired,
556 std::memory_order order = std::memory_order_seq_cst)
noexcept
562 hi::axis_aligned_rectangle& expected,
563 hi::axis_aligned_rectangle desired,
564 std::memory_order order = std::memory_order_seq_cst)
noexcept
569 hi::axis_aligned_rectangle
fetch_or(hi::axis_aligned_rectangle arg, std::memory_order = std::memory_order_seq_cst)
noexcept
577 hi::axis_aligned_rectangle
operator|=(hi::axis_aligned_rectangle arg)
noexcept
580 return _value |= arg;
584 hi::axis_aligned_rectangle _value;
585 mutable hi::unfair_mutex _mutex;
588template<
typename CharT>
589struct std::formatter<
hi::axis_aligned_rectangle, CharT> : std::formatter<float, CharT> {
595 auto format(hi::axis_aligned_rectangle
const& t,
auto& fc)
597 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 utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
constexpr alignment operator|(horizontal_alignment lhs, vertical_alignment rhs) noexcept
Combine vertical and horizontal alignment.
Definition alignment.hpp:200
@ bottom
Align to the bottom.
@ inside
The border is drawn inside the edge of a quad.
@ outside
The border is drawn outside the edge of a quad.
The HikoGUI namespace.
Definition ascii.hpp:19
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:430
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:214
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:446
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:370
constexpr bool empty() const noexcept
Check if the rectangle has no area.
Definition axis_aligned_rectangle.hpp:102
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:313
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:305
friend constexpr axis_aligned_rectangle ceil(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by expanding to pixel edge.
Definition axis_aligned_rectangle.hpp:412
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:119
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:398
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:95
constexpr axis_aligned_rectangle & operator|=(point2 const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:129
constexpr extent2 size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:170
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:421
constexpr bool contains(point2 const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:242
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:387
constexpr bool contains(point3 const &rhs) const noexcept
Check if a 3D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:253
constexpr float middle() const noexcept
The middle on the y-axis between bottom and top.
Definition axis_aligned_rectangle.hpp:207
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:221
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:265
constexpr axis_aligned_rectangle(point2 const &p0, extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:81
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
T compare_exchange_weak(T... args)
T is_lock_free(T... args)