HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
quad.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
6#pragma once
7
8#include "vector3.hpp"
9#include "point3.hpp"
10#include "extent3.hpp"
11#include "aarectangle.hpp"
12#include "rectangle.hpp"
13#include "../macros.hpp"
14#include <tuple>
15
16namespace hi::inline v1 {
17
18class quad {
19public:
24
25 constexpr quad() noexcept : p0(), p1(), p2(), p3() {}
26
27 constexpr quad(point3 p0, point3 p1, point3 p2, point3 p3) noexcept : p0(p0), p1(p1), p2(p2), p3(p3) {}
28
29 constexpr quad(quad const &) noexcept = default;
30 constexpr quad(quad &&) noexcept = default;
31 constexpr quad &operator=(quad const &) noexcept = default;
32 constexpr quad &operator=(quad &&) noexcept = default;
33
34 constexpr quad(aarectangle const &rhs) noexcept
35 {
36 hilet tmp = f32x4{rhs};
37 p0 = point3{tmp.xy01()};
38 p1 = point3{tmp.zy01()};
39 p2 = point3{tmp.xw01()};
40 p3 = point3{tmp.zw01()};
41 }
42
43 constexpr quad(rectangle const &rhs) noexcept : p0(get<0>(rhs)), p1(get<1>(rhs)), p2(get<2>(rhs)), p3(get<3>(rhs)) {}
44
47 [[nodiscard]] constexpr vector3 bottom() const noexcept
48 {
49 return p1 - p0;
50 }
51
54 [[nodiscard]] constexpr vector3 top() const noexcept
55 {
56 return p3 - p2;
57 }
58
61 [[nodiscard]] constexpr vector3 left() const noexcept
62 {
63 return p2 - p0;
64 }
65
68 [[nodiscard]] constexpr vector3 right() const noexcept
69 {
70 return p3 - p1;
71 }
72
77 [[nodiscard]] constexpr f32x4 edge_hypots() const noexcept
78 {
79 hilet[x, y, z, zeros] = transpose(f32x4{bottom()}, f32x4{left()}, f32x4{top()}, f32x4{right()});
80 return sqrt(x * x + y * y + z * z);
81 }
82
83 [[nodiscard]] constexpr point3 &operator[](std::size_t index) noexcept
84 {
85 switch (index) {
86 case 0: return p0;
87 case 1: return p1;
88 case 2: return p2;
89 case 3: return p3;
90 default: hi_no_default();
91 }
92 }
93
94 [[nodiscard]] constexpr point3 const &operator[](std::size_t index) const noexcept
95 {
96 switch (index) {
97 case 0: return p0;
98 case 1: return p1;
99 case 2: return p2;
100 case 3: return p3;
101 default: hi_no_default();
102 }
103 }
104
105 template<std::size_t I>
106 [[nodiscard]] constexpr friend point3 const &get(quad const &rhs) noexcept
107 {
108 static_assert(I < 4, "Index out of range.");
109
110 if constexpr (I == 0) {
111 return rhs.p0;
112 } else if constexpr (I == 1) {
113 return rhs.p1;
114 } else if constexpr (I == 2) {
115 return rhs.p2;
116 } else {
117 return rhs.p3;
118 }
119 }
120
121 template<std::size_t I>
122 [[nodiscard]] constexpr friend point3 &get(quad &rhs) noexcept
123 {
124 static_assert(I < 4, "Index out of range.");
125
126 if constexpr (I == 0) {
127 return rhs.p0;
128 } else if constexpr (I == 1) {
129 return rhs.p1;
130 } else if constexpr (I == 2) {
131 return rhs.p2;
132 } else {
133 return rhs.p3;
134 }
135 }
136
145 [[nodiscard]] friend constexpr std::pair<quad, f32x4> expand_and_edge_hypots(quad const &lhs, f32x4 const &rhs) noexcept
146 {
147 hilet t = f32x4{lhs.top()};
148 hilet l = f32x4{lhs.left()};
149 hilet b = f32x4{lhs.bottom()};
150 hilet r = f32x4{lhs.right()};
151
152 hilet[x, y, z, ones] = transpose(t, l, b, r);
153 hilet square_lengths = x * x + y * y + z * z;
154 hilet inv_lengths = rcp_sqrt(square_lengths);
155 hilet norm_t = t * inv_lengths.xxxx();
156 hilet norm_l = l * inv_lengths.yyyy();
157 hilet norm_b = b * inv_lengths.zzzz();
158 hilet norm_r = r * inv_lengths.wwww();
159
160 hilet extra_width = rhs.xxxx();
161 hilet extra_height = rhs.yyyy();
162
163 hilet top_extra = vector3{norm_t * extra_width};
164 hilet left_extra = vector3{norm_l * extra_height};
165 hilet bottom_extra = vector3{norm_b * extra_width};
166 hilet right_extra = vector3{norm_r * extra_height};
167
168 hilet lengths = rcp(inv_lengths);
169
170 hilet rhs_times_2 = rhs + rhs;
171
172 return {
173 quad{
174 lhs.p0 - bottom_extra - left_extra,
175 lhs.p1 + bottom_extra - right_extra,
176 lhs.p2 - top_extra + left_extra,
177 lhs.p3 + top_extra + right_extra},
178 lengths + rhs_times_2.xyxy()};
179 }
180
189 [[nodiscard]] friend constexpr std::pair<quad, f32x4> expand_and_edge_hypots(quad const &lhs, extent2 const &rhs) noexcept
190 {
191 return expand_and_edge_hypots(lhs, f32x4{rhs});
192 }
193
202 [[nodiscard]] friend constexpr std::pair<quad, f32x4> shrink_and_edge_hypots(quad const &lhs, extent2 const &rhs) noexcept
203 {
204 return expand_and_edge_hypots(lhs, -f32x4{rhs});
205 }
206
215 [[nodiscard]] friend constexpr quad operator+(quad const &lhs, extent2 const &rhs) noexcept
216 {
217 hilet[expanded_quad, new_lengths] = expand_and_edge_hypots(lhs, rhs);
218 return expanded_quad;
219 }
220
221 [[nodiscard]] friend constexpr quad operator+(quad const &lhs, float rhs) noexcept
222 {
223 return lhs + extent2{rhs, rhs};
224 }
225
234 [[nodiscard]] friend constexpr quad operator-(quad const &lhs, extent2 const &rhs) noexcept
235 {
236 hilet[expanded_quad, new_lengths] = shrink_and_edge_hypots(lhs, rhs);
237 return expanded_quad;
238 }
239
240 [[nodiscard]] friend constexpr quad operator-(quad const &lhs, float rhs) noexcept
241 {
242 return lhs - extent2{rhs, rhs};
243 }
244
245 [[nodiscard]] friend constexpr aarectangle bounding_rectangle(quad const &rhs) noexcept
246 {
247 auto min_p = rhs.p0;
248 auto max_p = rhs.p0;
249
250 min_p = min(min_p, rhs.p1);
251 max_p = max(max_p, rhs.p1);
252 min_p = min(min_p, rhs.p2);
253 max_p = max(max_p, rhs.p2);
254 min_p = min(min_p, rhs.p3);
255 max_p = max(max_p, rhs.p3);
256 return aarectangle{point2{min_p}, point2{max_p}};
257 }
258
259 constexpr quad &operator+=(extent2 const &rhs) noexcept
260 {
261 return *this = *this + rhs;
262 }
263
264 [[nodiscard]] friend constexpr bool operator==(quad const &lhs, quad const &rhs) noexcept = default;
265};
266
267} // namespace hi::inline v1
Defined the geo::extent, extent2 and extent3 types.
DOXYGEN BUG.
Definition algorithm.hpp:16
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
A high-level geometric point Part of the high-level vec, point, mat and color types.
Definition point3.hpp:27
Definition quad.hpp:18
friend constexpr std::pair< quad, f32x4 > expand_and_edge_hypots(quad const &lhs, f32x4 const &rhs) noexcept
Add a border around the quad.
Definition quad.hpp:145
point3 p3
Right-top.
Definition quad.hpp:23
constexpr vector3 right() const noexcept
The vector from right-bottom to right-top.
Definition quad.hpp:68
friend constexpr std::pair< quad, f32x4 > shrink_and_edge_hypots(quad const &lhs, extent2 const &rhs) noexcept
Subtract a border from the quad.
Definition quad.hpp:202
point3 p1
Right-bottom.
Definition quad.hpp:21
friend constexpr quad operator+(quad const &lhs, extent2 const &rhs) noexcept
Add a border around the quad.
Definition quad.hpp:215
constexpr vector3 left() const noexcept
The vector from left-bottom to left-top.
Definition quad.hpp:61
friend constexpr quad operator-(quad const &lhs, extent2 const &rhs) noexcept
Add a border around the quad.
Definition quad.hpp:234
point3 p0
Left-bottom.
Definition quad.hpp:20
constexpr vector3 bottom() const noexcept
The vector from left-bottom to right-bottom.
Definition quad.hpp:47
constexpr vector3 top() const noexcept
The vector from left-top to right-top.
Definition quad.hpp:54
point3 p2
Left-top.
Definition quad.hpp:22
constexpr f32x4 edge_hypots() const noexcept
Return the length of each edge.
Definition quad.hpp:77
friend constexpr std::pair< quad, f32x4 > expand_and_edge_hypots(quad const &lhs, extent2 const &rhs) noexcept
Add a border around the quad.
Definition quad.hpp:189
T max(T... args)
T min(T... args)