14#include "../rapid/numeric_array.hpp"
15#include "../concepts.hpp"
16#include "../unfair_mutex.hpp"
22namespace hi {
inline namespace v1 {
31 using array_type = numeric_array<value_type, 4>;
44 point<value_type, 2>{-large_number_v<value_type>, -large_number_v<value_type>},
45 point<value_type, 2>{large_number_v<value_type>, large_number_v<value_type>}};
61 v{x, y, x + width, y + height}
71 v(
static_cast<array_type
>(
extent)._00xy())
81 v(
static_cast<array_type
>(p0).xy00() +
static_cast<array_type
>(p3)._00xy())
96 v(
static_cast<array_type
>(p0).xyxy() +
static_cast<array_type
>(
extent)._00xy())
101 constexpr explicit operator array_type() const noexcept
111 return le(v, v.zwzw()) == 0b1111;
116 [[nodiscard]]
constexpr bool empty() const noexcept
118 return eq(v, v.zwxy()) == 0b1111;
123 [[nodiscard]]
constexpr explicit operator bool() const noexcept
135 return *
this = *
this | rhs;
145 return *
this = *
this | rhs;
148 [[nodiscard]]
constexpr point<value_type, 2> operator[](
std::size_t i)
const noexcept
152 return point<value_type, 2>{v.xy01()};
154 return point<value_type, 2>{v.zy01()};
156 return point<value_type, 2>{v.xw01()};
158 return point<value_type, 2>{v.zw01()};
165 [[nodiscard]]
constexpr friend point<value_type, 2> get(axis_aligned_rectangle
const& rhs)
noexcept
167 if constexpr (I == 0) {
168 return point<value_type, 2>{rhs.v.xy01()};
169 }
else if constexpr (I == 1) {
170 return point<value_type, 2>{rhs.v.zy01()};
171 }
else if constexpr (I == 2) {
172 return point<value_type, 2>{rhs.v.xw01()};
173 }
else if constexpr (I == 3) {
174 return point<value_type, 2>{rhs.v.zw01()};
189 [[nodiscard]]
constexpr value_type x() const noexcept
194 [[nodiscard]]
constexpr value_type y() const noexcept
199 [[nodiscard]]
constexpr value_type width() const noexcept
201 return (v.zwzw() - v).x();
204 [[nodiscard]]
constexpr value_type height() const noexcept
206 return (v.zwzw() - v).y();
209 [[nodiscard]]
constexpr value_type bottom() const noexcept
214 [[nodiscard]]
constexpr value_type top() const noexcept
219 [[nodiscard]]
constexpr value_type left() const noexcept
224 [[nodiscard]]
constexpr value_type right() const noexcept
231 [[nodiscard]]
constexpr value_type
middle() const noexcept
233 return (bottom() + top()) / value_type{2};
238 [[nodiscard]]
constexpr value_type
center() const noexcept
240 return (left() + right()) / value_type{2};
247 return midpoint(get<0>(rhs), get<3>(rhs));
252 v = v.xyxw() + array_type{value_type{0}, value_type{0}, newWidth, value_type{0}};
256 constexpr axis_aligned_rectangle& set_height(value_type newHeight)
noexcept
258 v = v.xyzy() + array_type{value_type{0}, value_type{0}, value_type{0}, newHeight};
266 [[nodiscard]]
constexpr bool contains(point<value_type, 2>
const& rhs)
const noexcept
269 return ge(
static_cast<array_type
>(rhs).xyxy(), v) == 0b0011;
277 [[nodiscard]]
constexpr bool contains(point<value_type, 3>
const& rhs)
const noexcept
279 return contains(point<value_type, 2>{rhs});
291 auto x = value_type{0};
292 if (alignment == horizontal_alignment::left) {
295 }
else if (alignment == horizontal_alignment::right) {
296 x = haystack.right() - needle.width();
298 }
else if (alignment == horizontal_alignment::center) {
299 x = haystack.center() - needle.width() / value_type{2};
305 auto y = value_type{0};
306 if (alignment == vertical_alignment::bottom) {
307 y = haystack.bottom();
309 }
else if (alignment == vertical_alignment::top) {
310 y = haystack.top() - needle.height();
312 }
else if (alignment == vertical_alignment::middle) {
313 y = haystack.middle() - needle.height() / value_type{2};
319 return {point<value_type, 2>{x, y}, needle};
331 return align(haystack, needle.size(), alignment);
339 return align(outside, inside, alignment);
344 return lhs.v == rhs.v;
347 [[nodiscard]]
friend constexpr bool overlaps(axis_aligned_rectangle
const& lhs, axis_aligned_rectangle
const& rhs)
noexcept
349 if (lhs.empty() or rhs.
empty()) {
353 hilet rhs_swap = rhs.v.zwxy();
356 if ((gt(lhs.v, rhs_swap) & 0b0011) != 0) {
361 if ((lt(lhs.v, rhs_swap) & 0b1100) != 0) {
368 [[nodiscard]]
friend constexpr axis_aligned_rectangle
369 operator|(axis_aligned_rectangle
const& lhs, axis_aligned_rectangle
const& rhs)
noexcept
376 return axis_aligned_rectangle{
min(get<0>(lhs), get<0>(rhs)),
max(get<3>(lhs), get<3>(rhs))};
380 [[nodiscard]]
friend constexpr axis_aligned_rectangle
381 operator|(axis_aligned_rectangle
const& lhs, point<value_type, 2>
const& rhs)
noexcept
384 return axis_aligned_rectangle{rhs, rhs};
386 return axis_aligned_rectangle{
min(get<0>(lhs), rhs),
max(get<3>(lhs), rhs)};
398 hilet diff = vector<value_type, 2>{new_extent} - vector<value_type, 2>{lhs.
size()};
399 hilet offset = diff * 0.5f;
401 hilet p0 = get<0>(lhs) - offset;
402 hilet p3 = max(get<3>(lhs) + offset, p0);
429 requires std::is_same_v<value_type, float>
431 hilet p0 = round(get<0>(rhs));
439 requires std::is_same_v<value_type, float>
459 requires std::is_same_v<value_type, float>
474 [[nodiscard]]
friend constexpr axis_aligned_rectangle
477 hilet p0 = max(get<0>(lhs), get<0>(rhs));
478 hilet p3 = min(get<3>(lhs), get<3>(rhs));
479 if (p0.x() < p3.x() && p0.y() < p3.y()) {
486 [[nodiscard]]
constexpr friend value_type
489 hilet lhs_ =
static_cast<array_type
>(lhs);
490 hilet rhs_ =
static_cast<array_type
>(rhs);
492 hilet closest_point = max(min(rhs_, lhs_.zwzw()), lhs_);
493 hilet v_closest_point = closest_point - rhs_;
494 return hypot<0b0011>(v_closest_point);
508using aarectangle = geo::axis_aligned_rectangle<float>;
509using aarectanglei = geo::axis_aligned_rectangle<int>;
527[[nodiscard]] aarectanglei
fit(aarectanglei
const& bounds, aarectanglei
const&
rectangle)
noexcept;
530[[nodiscard]]
constexpr aarectanglei narrow_cast(
aarectangle const& rhs)
noexcept
532 return {narrow_cast<int>(rhs.x()), narrow_cast<int>(rhs.y()), narrow_cast<int>(rhs.width()), narrow_cast<int>(rhs.height())};
536[[nodiscard]]
constexpr aarectangle narrow_cast(aarectanglei
const& rhs)
noexcept
539 narrow_cast<float>(rhs.x()),
540 narrow_cast<float>(rhs.y()),
541 narrow_cast<float>(rhs.width()),
542 narrow_cast<float>(rhs.height())};
550 using value_type = hi::geo::axis_aligned_rectangle<T>;
551 static constexpr bool is_always_lock_free =
false;
553 constexpr atomic()
noexcept =
default;
559 constexpr atomic(value_type
const& rhs) noexcept : _value(rhs) {}
566 operator value_type()
const noexcept
573 return is_always_lock_free;
576 void store(value_type desired, std::memory_order = std::memory_order_seq_cst)
noexcept
582 value_type
load(std::memory_order = std::memory_order_seq_cst)
const noexcept
588 value_type
exchange(value_type desired, std::memory_order = std::memory_order_seq_cst)
noexcept
591 return std::exchange(_value, desired);
594 bool compare_exchange_weak(value_type& expected, value_type desired, std::memory_order, std::memory_order)
noexcept
597 if (_value == expected) {
607 value_type& expected,
609 std::memory_order success,
610 std::memory_order failure)
noexcept
616 compare_exchange_weak(value_type& expected, value_type desired, std::memory_order order = std::memory_order_seq_cst)
noexcept
622 value_type& expected,
624 std::memory_order order = std::memory_order_seq_cst)
noexcept
629 value_type
fetch_or(value_type arg, std::memory_order = std::memory_order_seq_cst)
noexcept
637 value_type
operator|=(value_type arg)
noexcept
640 return _value |= arg;
645 mutable hi::unfair_mutex _mutex;
648template<
typename CharT>
649struct std::formatter<
hi::geo::axis_aligned_rectangle<float>, CharT> {
655 auto format(hi::geo::axis_aligned_rectangle<float>
const& t,
auto& fc)
657 return std::vformat_to(fc.out(),
"{}:{}", std::make_format_args(get<0>(t), t.size()));
661template<
typename CharT>
662struct std::formatter<
hi::geo::axis_aligned_rectangle<int>, CharT> {
668 auto format(hi::geo::axis_aligned_rectangle<int>
const& t,
auto& fc)
670 return std::vformat_to(fc.out(),
"{}:{}", std::make_format_args(get<0>(t), t.size()));
#define hi_static_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:181
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:148
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
Defined the geo::extent, extent2 and extent3 types.
types and utilities for alignment.
This file contains constants and conversion functions.
@ other
The gui_event does not have associated data.
@ rectangle
The gui_event has rectangle data.
DOXYGEN BUG.
Definition algorithm.hpp:15
geometry/margins.hpp
Definition assert.hpp:18
aarectangle fit(aarectangle const &bounds, aarectangle const &rectangle) noexcept
Make a rectangle fit inside bounds.
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:28
static constexpr axis_aligned_rectangle large() noexcept
Create a large axis aligned rectangle.
Definition axis_aligned_rectangle.hpp:41
friend constexpr axis_aligned_rectangle operator-(axis_aligned_rectangle const &lhs, value_type rhs) noexcept
Shrink the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:423
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:337
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:475
constexpr axis_aligned_rectangle(point< value_type, 2 > const &p0, extent< value_type, 2 > const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:95
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:329
friend constexpr axis_aligned_rectangle ceil(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by expanding to pixel edge.
Definition axis_aligned_rectangle.hpp:438
constexpr bool contains(point< value_type, 3 > const &rhs) const noexcept
Check if a 3D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:277
constexpr extent< value_type, 2 > size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:184
constexpr bool empty() const noexcept
Check if the rectangle has no area.
Definition axis_aligned_rectangle.hpp:116
constexpr bool holds_invariant() const noexcept
Make sure p0 is left/bottom from p3.
Definition axis_aligned_rectangle.hpp:109
constexpr bool contains(point< value_type, 2 > const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:266
friend constexpr axis_aligned_rectangle floor(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by shrinking to pixel edge.
Definition axis_aligned_rectangle.hpp:458
constexpr friend point< value_type, 2 > midpoint(axis_aligned_rectangle const &rhs) noexcept
Get the center of the rectangle.
Definition axis_aligned_rectangle.hpp:245
constexpr value_type center() const noexcept
The center on the x-axis between left and right.
Definition axis_aligned_rectangle.hpp:238
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:133
constexpr axis_aligned_rectangle(value_type x, value_type y, value_type width, value_type height) noexcept
Create a box from the position and size.
Definition axis_aligned_rectangle.hpp:60
friend constexpr axis_aligned_rectangle operator*(axis_aligned_rectangle const &lhs, value_type rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:395
friend constexpr axis_aligned_rectangle operator+(axis_aligned_rectangle const &lhs, value_type rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:412
constexpr value_type middle() const noexcept
The middle on the y-axis between bottom and top.
Definition axis_aligned_rectangle.hpp:231
constexpr axis_aligned_rectangle(point< value_type, 2 > const &p0, point< value_type, 2 > const &p3) noexcept
Create a rectangle from the left-bottom and right-top points.
Definition axis_aligned_rectangle.hpp:80
friend constexpr axis_aligned_rectangle align(axis_aligned_rectangle haystack, extent< value_type, 2 > needle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition axis_aligned_rectangle.hpp:289
constexpr axis_aligned_rectangle & operator|=(point< value_type, 2 > const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:143
constexpr axis_aligned_rectangle(extent< value_type, 2 > const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:70
friend constexpr axis_aligned_rectangle ceil(axis_aligned_rectangle const &lhs, extent< value_type, 2 > const &rhs) noexcept
Round rectangle by expanding to a certain granularity.
Definition axis_aligned_rectangle.hpp:449
A high-level geometric extent.
Definition extent.hpp:31
T compare_exchange_weak(T... args)
T is_lock_free(T... args)