15#include "../SIMD/module.hpp"
16#include "../utility/module.hpp"
17#include "../concurrency/module.hpp"
21namespace hi {
inline namespace v1 {
30 using array_type = simd<value_type, 4>;
43 point<value_type, 2>{-large_number_v<value_type>, -large_number_v<value_type>},
44 point<value_type, 2>{large_number_v<value_type>, large_number_v<value_type>}};
60 v{x, y, x + width, y + height}
70 v(
static_cast<array_type
>(
extent)._00xy())
80 v(
static_cast<array_type
>(p0).xy00() +
static_cast<array_type
>(p3)._00xy())
95 v(
static_cast<array_type
>(p0).xyxy() +
static_cast<array_type
>(
extent)._00xy())
100 constexpr explicit operator array_type() const noexcept
110 return (v <= v.zwzw()).mask() == 0b1111;
115 [[nodiscard]]
constexpr bool empty() const noexcept
117 return (v == v.zwxy()).mask() == 0b1111;
122 [[nodiscard]]
constexpr explicit operator bool() const noexcept
134 return *
this = *
this | rhs;
144 return *
this = *
this | rhs;
147 [[nodiscard]]
constexpr point<value_type, 2> operator[](
std::size_t i)
const noexcept
151 return point<value_type, 2>{v.xy01()};
153 return point<value_type, 2>{v.zy01()};
155 return point<value_type, 2>{v.xw01()};
157 return point<value_type, 2>{v.zw01()};
164 [[nodiscard]]
constexpr friend point<value_type, 2> get(axis_aligned_rectangle
const& rhs)
noexcept
166 if constexpr (I == 0) {
167 return point<value_type, 2>{rhs.v.xy01()};
168 }
else if constexpr (I == 1) {
169 return point<value_type, 2>{rhs.v.zy01()};
170 }
else if constexpr (I == 2) {
171 return point<value_type, 2>{rhs.v.xw01()};
172 }
else if constexpr (I == 3) {
173 return point<value_type, 2>{rhs.v.zw01()};
188 [[nodiscard]]
constexpr value_type x() const noexcept
193 [[nodiscard]]
constexpr value_type y() const noexcept
198 [[nodiscard]]
constexpr value_type width() const noexcept
200 return (v.zwzw() - v).x();
203 [[nodiscard]]
constexpr value_type height() const noexcept
205 return (v.zwzw() - v).y();
208 [[nodiscard]]
constexpr value_type bottom() const noexcept
213 [[nodiscard]]
constexpr value_type top() const noexcept
218 [[nodiscard]]
constexpr value_type left() const noexcept
223 [[nodiscard]]
constexpr value_type right() const noexcept
230 [[nodiscard]]
constexpr value_type
middle() const noexcept
232 return (bottom() + top()) / value_type{2};
237 [[nodiscard]]
constexpr value_type
center() const noexcept
239 return (left() + right()) / value_type{2};
246 return midpoint(get<0>(rhs), get<3>(rhs));
251 v = v.xyxw() + array_type{value_type{0}, value_type{0}, newWidth, value_type{0}};
255 constexpr axis_aligned_rectangle& set_height(value_type newHeight)
noexcept
257 v = v.xyzy() + array_type{value_type{0}, value_type{0}, value_type{0}, newHeight};
265 [[nodiscard]]
constexpr bool contains(point<value_type, 2>
const& rhs)
const noexcept
268 return (
static_cast<array_type
>(rhs).xyxy() >= v).mask() == 0b0011;
276 [[nodiscard]]
constexpr bool contains(point<value_type, 3>
const& rhs)
const noexcept
278 return contains(point<value_type, 2>{rhs});
290 auto x = value_type{0};
291 if (alignment == horizontal_alignment::left) {
294 }
else if (alignment == horizontal_alignment::right) {
295 x = haystack.right() - needle.width();
297 }
else if (alignment == horizontal_alignment::center) {
298 x = haystack.center() - needle.width() / value_type{2};
304 auto y = value_type{0};
305 if (alignment == vertical_alignment::bottom) {
306 y = haystack.bottom();
308 }
else if (alignment == vertical_alignment::top) {
309 y = haystack.top() - needle.height();
311 }
else if (alignment == vertical_alignment::middle) {
312 y = haystack.middle() - needle.height() / value_type{2};
318 return {point<value_type, 2>{x, y}, needle};
330 return align(haystack, needle.size(), alignment);
343 return equal(lhs.v, rhs.v);
346 [[nodiscard]]
friend constexpr bool overlaps(axis_aligned_rectangle
const& lhs, axis_aligned_rectangle
const& rhs)
noexcept
348 if (lhs.empty() or rhs.
empty()) {
352 hilet rhs_swap = rhs.v.zwxy();
355 if (((lhs.v > rhs_swap).mask() & 0b0011) != 0) {
360 if (((lhs.v < rhs_swap).mask() & 0b1100) != 0) {
367 [[nodiscard]]
friend constexpr axis_aligned_rectangle
368 operator|(axis_aligned_rectangle
const& lhs, axis_aligned_rectangle
const& rhs)
noexcept
375 return axis_aligned_rectangle{
min(get<0>(lhs), get<0>(rhs)),
max(get<3>(lhs), get<3>(rhs))};
379 [[nodiscard]]
friend constexpr axis_aligned_rectangle
380 operator|(axis_aligned_rectangle
const& lhs, point<value_type, 2>
const& rhs)
noexcept
383 return axis_aligned_rectangle{rhs, rhs};
385 return axis_aligned_rectangle{
min(get<0>(lhs), rhs),
max(get<3>(lhs), rhs)};
397 hilet diff = vector<value_type, 2>{new_extent} - vector<value_type, 2>{lhs.
size()};
398 hilet offset = diff * 0.5f;
400 hilet p0 = get<0>(lhs) - offset;
401 hilet p3 = max(get<3>(lhs) + offset, p0);
435 auto lhs_ =
static_cast<simd<value_type, 4>
>(lhs);
436 auto rhs_ =
static_cast<simd<value_type, 4>
>(rhs);
444 requires std::is_same_v<value_type, float>
446 hilet p0 = round(get<0>(rhs));
454 requires std::is_same_v<value_type, float>
474 requires std::is_same_v<value_type, float>
489 [[nodiscard]]
friend constexpr axis_aligned_rectangle
492 hilet p0 = max(get<0>(lhs), get<0>(rhs));
493 hilet p3 = min(get<3>(lhs), get<3>(rhs));
494 if (p0.x() < p3.x() && p0.y() < p3.y()) {
501 [[nodiscard]]
constexpr friend value_type
504 hilet lhs_ =
static_cast<array_type
>(lhs);
505 hilet rhs_ =
static_cast<array_type
>(rhs);
507 hilet closest_point = max(min(rhs_, lhs_.zwzw()), lhs_);
508 hilet v_closest_point = closest_point - rhs_;
509 return hypot<0b0011>(v_closest_point);
523using aarectangle = geo::axis_aligned_rectangle<float>;
524using aarectanglei = geo::axis_aligned_rectangle<int>;
542[[nodiscard]] aarectanglei
fit(aarectanglei
const& bounds, aarectanglei
const&
rectangle)
noexcept;
545[[nodiscard]]
constexpr aarectanglei narrow_cast(
aarectangle const& rhs)
noexcept
547 return {narrow_cast<int>(rhs.x()), narrow_cast<int>(rhs.y()), narrow_cast<int>(rhs.width()), narrow_cast<int>(rhs.height())};
551[[nodiscard]]
constexpr aarectangle narrow_cast(aarectanglei
const& rhs)
noexcept
554 narrow_cast<float>(rhs.x()),
555 narrow_cast<float>(rhs.y()),
556 narrow_cast<float>(rhs.width()),
557 narrow_cast<float>(rhs.height())};
565 using value_type = hi::geo::axis_aligned_rectangle<T>;
566 static constexpr bool is_always_lock_free =
false;
568 constexpr atomic()
noexcept =
default;
574 constexpr atomic(value_type
const& rhs) noexcept : _value(rhs) {}
581 operator value_type()
const noexcept
588 return is_always_lock_free;
591 void store(value_type desired, std::memory_order = std::memory_order_seq_cst)
noexcept
597 value_type
load(std::memory_order = std::memory_order_seq_cst)
const noexcept
603 value_type
exchange(value_type desired, std::memory_order = std::memory_order_seq_cst)
noexcept
606 return std::exchange(_value, desired);
609 bool compare_exchange_weak(value_type& expected, value_type desired, std::memory_order, std::memory_order)
noexcept
612 if (_value == expected) {
622 value_type& expected,
624 std::memory_order success,
625 std::memory_order failure)
noexcept
631 compare_exchange_weak(value_type& expected, value_type desired, std::memory_order order = std::memory_order_seq_cst)
noexcept
637 value_type& expected,
639 std::memory_order order = std::memory_order_seq_cst)
noexcept
644 value_type
fetch_or(value_type arg, std::memory_order = std::memory_order_seq_cst)
noexcept
652 value_type
operator|=(value_type arg)
noexcept
655 return _value |= arg;
663template<
typename CharT>
664struct std::formatter<
hi::geo::axis_aligned_rectangle<float>, CharT> {
670 auto format(hi::geo::axis_aligned_rectangle<float>
const& t,
auto& fc)
672 return std::vformat_to(fc.out(),
"{}:{}", std::make_format_args(get<0>(t), t.size()));
676template<
typename CharT>
677struct std::formatter<
hi::geo::axis_aligned_rectangle<int>, CharT> {
683 auto format(hi::geo::axis_aligned_rectangle<int>
const& t,
auto& fc)
685 return std::vformat_to(fc.out(),
"{}:{}", std::make_format_args(get<0>(t), t.size()));
Defined the geo::extent, extent2 and extent3 types.
types and utilities for alignment.
#define hi_static_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:323
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:279
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
@ other
The gui_event does not have associated data.
@ rectangle
The gui_event has rectangle data.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
aarectangle fit(aarectangle const &bounds, aarectangle const &rectangle) noexcept
Make a rectangle fit inside bounds.
@ inside
The border is drawn inside the edge of a quad.
@ outside
The border is drawn outside the edge of a quad.
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:27
static constexpr axis_aligned_rectangle large() noexcept
Create a large axis aligned rectangle.
Definition axis_aligned_rectangle.hpp:40
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:422
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:336
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:490
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:94
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:328
friend constexpr axis_aligned_rectangle ceil(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by expanding to pixel edge.
Definition axis_aligned_rectangle.hpp:453
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:276
constexpr extent< value_type, 2 > size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:183
constexpr bool empty() const noexcept
Check if the rectangle has no area.
Definition axis_aligned_rectangle.hpp:115
friend constexpr axis_aligned_rectangle operator-(axis_aligned_rectangle const &lhs, geo::margins< value_type > rhs) noexcept
Shrink the rectangle by each margin.
Definition axis_aligned_rectangle.hpp:433
constexpr bool holds_invariant() const noexcept
Make sure p0 is left/bottom from p3.
Definition axis_aligned_rectangle.hpp:108
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:265
friend constexpr axis_aligned_rectangle floor(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by shrinking to pixel edge.
Definition axis_aligned_rectangle.hpp:473
constexpr friend point< value_type, 2 > midpoint(axis_aligned_rectangle const &rhs) noexcept
Get the center of the rectangle.
Definition axis_aligned_rectangle.hpp:244
constexpr value_type center() const noexcept
The center on the x-axis between left and right.
Definition axis_aligned_rectangle.hpp:237
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:132
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:59
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:394
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:411
constexpr value_type middle() const noexcept
The middle on the y-axis between bottom and top.
Definition axis_aligned_rectangle.hpp:230
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:79
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:288
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:142
constexpr axis_aligned_rectangle(extent< value_type, 2 > const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:69
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:464
A high-level geometric extent.
Definition extent.hpp:30
The left, bottom, right and top margins.
Definition margins.hpp:21
T compare_exchange_weak(T... args)
T is_lock_free(T... args)