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 "../macros.hpp"
10#include <hikocpu/hikocpu.hpp>
11#include <array>
12#include <exception>
13#include <compare>
14
15hi_export_module(hikogui.geometry : rectangle);
16
17hi_export namespace hi { inline namespace v1 {
18
25class rectangle {
26public:
27 point3 origin;
28 vector3 right;
29 vector3 up;
30
31 constexpr rectangle() noexcept : origin(), right(), up() {}
32 constexpr rectangle(rectangle const& rhs) noexcept = default;
33 constexpr rectangle& operator=(rectangle const& rhs) noexcept = default;
34 constexpr rectangle(rectangle&& rhs) noexcept = default;
35 constexpr rectangle& operator=(rectangle&& rhs) noexcept = default;
36
43 constexpr rectangle(point3 origin, vector3 right, vector3 up) noexcept : origin(origin), right(right), up(up) {}
44
52 constexpr rectangle(point3 origin, point3 right_bottom, point3 left_top, point3 right_top) noexcept :
53 rectangle(origin, right_bottom - origin, left_top - origin)
54 {
55 }
56
57 constexpr rectangle(aarectangle rhs) noexcept
58 {
59 auto const p0 = get<0>(rhs);
60 auto const p3 = get<3>(rhs);
61 auto const diagonal = static_cast<f32x4>(p3 - p0);
62
63 origin = p0;
64 right = vector3{diagonal.x000()};
65 up = vector3{diagonal._0y00()};
66 }
67
68 constexpr explicit rectangle(extent2 size) noexcept :
69 rectangle(point3{}, vector3{size.width(), 0.0f, 0.0f}, vector3{0.0f, size.height(), 0.0f})
70 {
71 }
72
73 constexpr rectangle& operator=(aarectangle rhs) noexcept
74 {
75 auto const p0 = get<0>(rhs);
76 auto const p3 = get<3>(rhs);
77 auto const diagonal = static_cast<f32x4>(p3 - p0);
78
79 origin = p0;
80 right = vector3{diagonal.x000()};
81 up = vector3{diagonal._0y00()};
82 return *this;
83 }
84
85 constexpr rectangle(point3 origin, extent2 extent) noexcept : rectangle(origin, extent.right(), extent.up()) {}
86
89 [[nodiscard]] constexpr friend aarectangle bounding_rectangle(rectangle const &rhs) noexcept
90 {
91 auto left_bottom = f32x4::broadcast(std::numeric_limits<float>::max());
92 auto right_top = f32x4::broadcast(-std::numeric_limits<float>::max());
93
94 auto const p0 = rhs.origin;
95 left_bottom = min(left_bottom, static_cast<f32x4>(p0));
96 right_top = max(right_top, static_cast<f32x4>(p0));
97
98 auto const p1 = p0 + rhs.right;
99 left_bottom = min(left_bottom, static_cast<f32x4>(p1));
100 right_top = max(right_top, static_cast<f32x4>(p1));
101
102 auto const p2 = p0 + rhs.up;
103 left_bottom = min(left_bottom, static_cast<f32x4>(p2));
104 right_top = max(right_top, static_cast<f32x4>(p2));
105
106 auto const p3 = p2 + rhs.right;
107 left_bottom = min(left_bottom, static_cast<f32x4>(p3));
108 right_top = max(right_top, static_cast<f32x4>(p3));
109
110 return aarectangle{left_bottom.xy00() | right_top._00xy()};
111 }
112
117 [[nodiscard]] explicit operator bool() const noexcept
118 {
119 // min() is smallest normal float.
120 return area() > std::numeric_limits<float>::min();
121 }
122
127 [[nodiscard]] constexpr bool is_rectangle() const noexcept
128 {
129 auto const dp = dot(right, up);
130 return -std::numeric_limits<float>::min() <= dp and dp <= std::numeric_limits<float>::min();
131 }
132
137 [[nodiscard]] constexpr bool is_axis_aligned() const noexcept
138 {
139 auto const should_be_zeroes = static_cast<f32x4>(right).yz00() | static_cast<f32x4>(up)._00xz();
140 return equal(should_be_zeroes, f32x4{});
141 }
142
145 [[nodiscard]] float width() const noexcept
146 {
147 return hypot(right);
148 }
149
152 [[nodiscard]] float height() const noexcept
153 {
154 return hypot(up);
155 }
156
159 [[nodiscard]] constexpr extent2 size() const noexcept
160 {
161 return {width(), height()};
162 }
163
164 [[nodiscard]] float area() const noexcept
165 {
166 return hypot(cross(right, up));
167 }
168
169 [[nodiscard]] constexpr point3 operator[](std::size_t i) const noexcept
170 {
171 switch (i) {
172 case 0:
173 return get<0>(*this);
174 case 1:
175 return get<1>(*this);
176 case 2:
177 return get<2>(*this);
178 case 3:
179 return get<3>(*this);
180 default:
181 hi_no_default();
182 }
183 }
184
185 template<std::size_t I>
186 [[nodiscard]] friend constexpr point3 get(rectangle const& rhs) noexcept
187 {
188 static_assert(I < 4);
189 if constexpr (I == 0) {
190 return rhs.origin;
191 } else if constexpr (I == 1) {
192 return rhs.origin + rhs.right;
193 } else if constexpr (I == 2) {
194 return rhs.origin + rhs.up;
195 } else {
196 return rhs.origin + rhs.right + rhs.up;
197 }
198 }
199
213 [[nodiscard]] friend constexpr rectangle operator+(rectangle const& lhs, extent2 rhs) noexcept
214 {
215 auto const extra_right = normalize(lhs.right) * rhs.width();
216 auto const extra_up = normalize(lhs.up) * rhs.height();
217 auto const extra_diagonal = extra_right + extra_up;
218
219 return rectangle{lhs.origin - extra_diagonal, lhs.right + 2.0f * extra_right, lhs.up + 2.0f * extra_up};
220 }
221
235 [[nodiscard]] friend constexpr rectangle operator-(rectangle const& lhs, extent2 rhs) noexcept
236 {
237 auto const extra_right = normalize(lhs.right) * rhs.width();
238 auto const extra_up = normalize(lhs.up) * rhs.height();
239 auto const extra_diagonal = extra_right + extra_up;
240
241 return rectangle{lhs.origin + extra_diagonal, lhs.right - 2.0f * extra_right, lhs.up - 2.0f * extra_up};
242 }
243
257 [[nodiscard]] friend constexpr rectangle operator+(rectangle const& lhs, float rhs) noexcept
258 {
259 return lhs + extent2{rhs, rhs};
260 };
261
275 [[nodiscard]] friend constexpr rectangle operator-(rectangle const& lhs, float rhs) noexcept
276 {
277 return lhs - extent2{rhs, rhs};
278 }
279};
280
281}} // namespace hi::v1
types and utilities for alignment.
@ rectangle
The gui_event has rectangle data.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:33
A high-level geometric extent.
Definition extent2.hpp:32
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent2.hpp:107
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent2.hpp:118
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:25
constexpr bool is_axis_aligned() const noexcept
Check if this is an axis aligned rectangle.
Definition rectangle.hpp:137
float height() const noexcept
The height, or length of the up vector.
Definition rectangle.hpp:152
friend constexpr rectangle operator-(rectangle const &lhs, float rhs) noexcept
Shrink the rectangle by subtracting an absolute distance from each side.
Definition rectangle.hpp:275
friend constexpr rectangle operator-(rectangle const &lhs, extent2 rhs) noexcept
Shrink the rectangle by subtracting an absolute distance from each side.
Definition rectangle.hpp:235
friend constexpr rectangle operator+(rectangle const &lhs, extent2 rhs) noexcept
Expand the rectangle by adding an absolute distance on each side.
Definition rectangle.hpp:213
constexpr friend aarectangle bounding_rectangle(rectangle const &rhs) noexcept
Return the axis-aligned bounding rectangle of this rectangle.
Definition rectangle.hpp:89
friend constexpr rectangle operator+(rectangle const &lhs, float rhs) noexcept
Expand the rectangle by adding an absolute distance on each side.
Definition rectangle.hpp:257
constexpr rectangle(point3 origin, point3 right_bottom, point3 left_top, point3 right_top) noexcept
Create a rectangle from 4 corner points.
Definition rectangle.hpp:52
float width() const noexcept
The width, or length of the right vector.
Definition rectangle.hpp:145
constexpr extent2 size() const noexcept
The size, or length of the right and up vectors.
Definition rectangle.hpp:159
constexpr bool is_rectangle() const noexcept
Check if this is a rectangle.
Definition rectangle.hpp:127
constexpr rectangle(point3 origin, vector3 right, vector3 up) noexcept
Create a rectangle from a corner point and two vectors.
Definition rectangle.hpp:43
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector3.hpp:26
T right(T... args)
T min(T... args)