HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
rectangle.hpp
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "aarectangle.hpp"
8#include "alignment.hpp"
9#include "../SIMD/module.hpp"
10#include "../macros.hpp"
11#include <array>
12
13namespace hi { inline namespace v1 {
14
21class rectangle {
22public:
23 point3 origin;
24 vector3 right;
25 vector3 up;
26
27 constexpr rectangle() noexcept : origin(), right(), up() {}
28 constexpr rectangle(rectangle const& rhs) noexcept = default;
29 constexpr rectangle& operator=(rectangle const& rhs) noexcept = default;
30 constexpr rectangle(rectangle&& rhs) noexcept = default;
31 constexpr rectangle& operator=(rectangle&& rhs) noexcept = default;
32
39 constexpr rectangle(point3 origin, vector3 right, vector3 up) noexcept : origin(origin), right(right), up(up) {}
40
48 constexpr rectangle(point3 origin, point3 right_bottom, point3 left_top, point3 right_top) noexcept :
49 rectangle(origin, right_bottom - origin, left_top - origin)
50 {
51 }
52
53 constexpr rectangle(aarectangle rhs) noexcept
54 {
55 hilet p0 = get<0>(rhs);
56 hilet p3 = get<3>(rhs);
57 hilet diagonal = static_cast<f32x4>(p3 - p0);
58
59 origin = p0;
60 right = vector3{diagonal.x000()};
61 up = vector3{diagonal._0y00()};
62 }
63
64 constexpr explicit rectangle(extent2 size) noexcept :
65 rectangle(point3{}, vector3{size.width(), 0.0f, 0.0f}, vector3{0.0f, size.height(), 0.0f})
66 {
67 }
68
69 constexpr rectangle& operator=(aarectangle rhs) noexcept
70 {
71 hilet p0 = get<0>(rhs);
72 hilet p3 = get<3>(rhs);
73 hilet diagonal = static_cast<f32x4>(p3 - p0);
74
75 origin = p0;
76 right = vector3{diagonal.x000()};
77 up = vector3{diagonal._0y00()};
78 return *this;
79 }
80
81 constexpr rectangle(point3 origin, extent2 extent) noexcept : rectangle(origin, extent.right(), extent.up()) {}
82
85 [[nodiscard]] constexpr friend aarectangle bounding_rectangle(rectangle const &rhs) noexcept
86 {
87 auto left_bottom = f32x4::broadcast(std::numeric_limits<float>::max());
88 auto right_top = f32x4::broadcast(-std::numeric_limits<float>::max());
89
90 hilet p0 = rhs.origin;
91 left_bottom = min(left_bottom, static_cast<f32x4>(p0));
92 right_top = max(right_top, static_cast<f32x4>(p0));
93
94 hilet p1 = p0 + rhs.right;
95 left_bottom = min(left_bottom, static_cast<f32x4>(p1));
96 right_top = max(right_top, static_cast<f32x4>(p1));
97
98 hilet p2 = p0 + rhs.up;
99 left_bottom = min(left_bottom, static_cast<f32x4>(p2));
100 right_top = max(right_top, static_cast<f32x4>(p2));
101
102 hilet p3 = p2 + rhs.right;
103 left_bottom = min(left_bottom, static_cast<f32x4>(p3));
104 right_top = max(right_top, static_cast<f32x4>(p3));
105
106 return aarectangle{left_bottom.xy00() | right_top._00xy()};
107 }
108
113 [[nodiscard]] explicit operator bool() const noexcept
114 {
115 // min() is smallest normal float.
116 return area() > std::numeric_limits<float>::min();
117 }
118
124 {
125 hilet dp = dot(right, up);
127 }
128
134 {
135 hilet should_be_zeroes = static_cast<f32x4>(right).yz00() | static_cast<f32x4>(up)._00xz();
136 return equal(should_be_zeroes, f32x4{});
137 }
138
142 {
143 return hypot(right);
144 }
145
149 {
150 return hypot(up);
151 }
152
156 {
157 return {width(), height()};
158 }
159
160 [[nodiscard]] float area() const noexcept
161 {
162 return hypot(cross(right, up));
163 }
164
165 [[nodiscard]] constexpr point3 operator[](std::size_t i) const noexcept
166 {
167 switch (i) {
168 case 0:
169 return get<0>(*this);
170 case 1:
171 return get<1>(*this);
172 case 2:
173 return get<2>(*this);
174 case 3:
175 return get<3>(*this);
176 default:
177 hi_no_default();
178 }
179 }
180
181 template<std::size_t I>
182 [[nodiscard]] friend constexpr point3 get(rectangle const& rhs) noexcept
183 {
184 static_assert(I < 4);
185 if constexpr (I == 0) {
186 return rhs.origin;
187 } else if constexpr (I == 1) {
188 return rhs.origin + rhs.right;
189 } else if constexpr (I == 2) {
190 return rhs.origin + rhs.up;
191 } else {
192 return rhs.origin + rhs.right + rhs.up;
193 }
194 }
195
209 [[nodiscard]] friend constexpr rectangle operator+(rectangle const& lhs, extent2 rhs) noexcept
210 {
211 hilet extra_right = normalize(lhs.right) * rhs.width();
212 hilet extra_up = normalize(lhs.up) * rhs.height();
214
215 return rectangle{lhs.origin - extra_diagonal, lhs.right + 2.0f * extra_right, lhs.up + 2.0f * extra_up};
216 }
217
231 [[nodiscard]] friend constexpr rectangle operator-(rectangle const& lhs, extent2 rhs) noexcept
232 {
233 hilet extra_right = normalize(lhs.right) * rhs.width();
234 hilet extra_up = normalize(lhs.up) * rhs.height();
236
237 return rectangle{lhs.origin + extra_diagonal, lhs.right - 2.0f * extra_right, lhs.up - 2.0f * extra_up};
238 }
239
253 [[nodiscard]] friend constexpr rectangle operator+(rectangle const& lhs, float rhs) noexcept
254 {
255 return lhs + extent2{rhs, rhs};
256 };
257
271 [[nodiscard]] friend constexpr rectangle operator-(rectangle const& lhs, float rhs) noexcept
272 {
273 return lhs - extent2{rhs, rhs};
274 }
275};
276
277}} // namespace hi::v1
types and utilities for alignment.
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:29
A high-level geometric extent.
Definition extent2.hpp:29
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent2.hpp:104
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent2.hpp:115
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:21
constexpr bool is_axis_aligned() const noexcept
Check if this is an axis aligned rectangle.
Definition rectangle.hpp:133
float height() const noexcept
The height, or length of the up vector.
Definition rectangle.hpp:148
friend constexpr rectangle operator-(rectangle const &lhs, float rhs) noexcept
Shrink the rectangle by subtracting an absolute distance from each side.
Definition rectangle.hpp:271
friend constexpr rectangle operator-(rectangle const &lhs, extent2 rhs) noexcept
Shrink the rectangle by subtracting an absolute distance from each side.
Definition rectangle.hpp:231
friend constexpr rectangle operator+(rectangle const &lhs, extent2 rhs) noexcept
Expand the rectangle by adding an absolute distance on each side.
Definition rectangle.hpp:209
constexpr friend aarectangle bounding_rectangle(rectangle const &rhs) noexcept
Return the axis-aligned bounding rectangle of this rectangle.
Definition rectangle.hpp:85
friend constexpr rectangle operator+(rectangle const &lhs, float rhs) noexcept
Expand the rectangle by adding an absolute distance on each side.
Definition rectangle.hpp:253
constexpr rectangle(point3 origin, point3 right_bottom, point3 left_top, point3 right_top) noexcept
Create a rectangle from 4 corner points.
Definition rectangle.hpp:48
float width() const noexcept
The width, or length of the right vector.
Definition rectangle.hpp:141
constexpr extent2 size() const noexcept
The size, or length of the right and up vectors.
Definition rectangle.hpp:155
constexpr bool is_rectangle() const noexcept
Check if this is a rectangle.
Definition rectangle.hpp:123
constexpr rectangle(point3 origin, vector3 right, vector3 up) noexcept
Create a rectangle from a corner point and two vectors.
Definition rectangle.hpp:39
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector3.hpp:20
T right(T... args)
T min(T... args)