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 <array>
11
12namespace hi { inline namespace v1 {
13
20class rectangle {
21public:
22 point3 origin;
23 vector3 right;
24 vector3 up;
25
26 constexpr rectangle() noexcept : origin(), right(), up() {}
27 constexpr rectangle(rectangle const& rhs) noexcept = default;
28 constexpr rectangle& operator=(rectangle const& rhs) noexcept = default;
29 constexpr rectangle(rectangle&& rhs) noexcept = default;
30 constexpr rectangle& operator=(rectangle&& rhs) noexcept = default;
31
38 constexpr rectangle(point3 origin, vector3 right, vector3 up) noexcept : origin(origin), right(right), up(up) {}
39
47 constexpr rectangle(point3 origin, point3 right_bottom, point3 left_top, point3 right_top) noexcept :
48 rectangle(origin, right_bottom - origin, left_top - origin)
49 {
50 }
51
52 constexpr rectangle(aarectangle rhs) noexcept
53 {
54 hilet p0 = get<0>(rhs);
55 hilet p3 = get<3>(rhs);
56 hilet diagonal = static_cast<f32x4>(p3 - p0);
57
58 origin = p0;
59 right = vector3{diagonal.x000()};
60 up = vector3{diagonal._0y00()};
61 }
62
63 constexpr explicit rectangle(extent2 size) noexcept :
64 rectangle(point3{}, vector3{size.width(), 0.0f, 0.0f}, vector3{0.0f, size.height(), 0.0f})
65 {
66 }
67
68 constexpr rectangle& operator=(aarectangle rhs) noexcept
69 {
70 hilet p0 = get<0>(rhs);
71 hilet p3 = get<3>(rhs);
72 hilet diagonal = static_cast<f32x4>(p3 - p0);
73
74 origin = p0;
75 right = vector3{diagonal.x000()};
76 up = vector3{diagonal._0y00()};
77 return *this;
78 }
79
80 constexpr rectangle(point3 origin, extent2 extent) noexcept : rectangle(origin, extent.right(), extent.up()) {}
81
84 [[nodiscard]] constexpr explicit operator aarectangle() const noexcept
85 {
86 auto left_bottom = f32x4::broadcast(std::numeric_limits<float>::max());
87 auto right_top = f32x4::broadcast(-std::numeric_limits<float>::max());
88
89 hilet p0 = origin;
90 left_bottom = min(left_bottom, static_cast<f32x4>(p0));
91 right_top = max(right_top, static_cast<f32x4>(p0));
92
93 hilet p1 = p0 + right;
94 left_bottom = min(left_bottom, static_cast<f32x4>(p1));
95 right_top = max(right_top, static_cast<f32x4>(p1));
96
97 hilet p2 = p0 + up;
98 left_bottom = min(left_bottom, static_cast<f32x4>(p2));
99 right_top = max(right_top, static_cast<f32x4>(p2));
100
101 hilet p3 = p2 + right;
102 left_bottom = min(left_bottom, static_cast<f32x4>(p3));
103 right_top = max(right_top, static_cast<f32x4>(p3));
104
105 return aarectangle{left_bottom.xy00() | right_top._00xy()};
106 }
107
112 [[nodiscard]] explicit operator bool() const noexcept
113 {
114 // min() is smallest normal float.
115 return area() > std::numeric_limits<float>::min();
116 }
117
122 [[nodiscard]] constexpr bool is_rectangle() const noexcept
123 {
124 hilet dp = dot(right, up);
125 return -std::numeric_limits<float>::min() <= dp and dp <= std::numeric_limits<float>::min();
126 }
127
132 [[nodiscard]] constexpr bool is_axis_aligned() const noexcept
133 {
134 hilet should_be_zeroes = static_cast<f32x4>(right).yz00() | static_cast<f32x4>(up)._00xz();
135 return equal(should_be_zeroes, f32x4{});
136 }
137
140 [[nodiscard]] float width() const noexcept
141 {
142 return hypot(right);
143 }
144
147 [[nodiscard]] float height() const noexcept
148 {
149 return hypot(up);
150 }
151
154 [[nodiscard]] constexpr extent2 size() const noexcept
155 {
156 return {width(), height()};
157 }
158
159 [[nodiscard]] float area() const noexcept
160 {
161 return hypot(cross(right, up));
162 }
163
164 [[nodiscard]] constexpr point3 operator[](std::size_t i) const noexcept
165 {
166 switch (i) {
167 case 0:
168 return get<0>(*this);
169 case 1:
170 return get<1>(*this);
171 case 2:
172 return get<2>(*this);
173 case 3:
174 return get<3>(*this);
175 default:
177 }
178 }
179
180 template<std::size_t I>
181 [[nodiscard]] friend constexpr point3 get(rectangle const& rhs) noexcept
182 {
183 static_assert(I < 4);
184 if constexpr (I == 0) {
185 return rhs.origin;
186 } else if constexpr (I == 1) {
187 return rhs.origin + rhs.right;
188 } else if constexpr (I == 2) {
189 return rhs.origin + rhs.up;
190 } else {
191 return rhs.origin + rhs.right + rhs.up;
192 }
193 }
194
208 [[nodiscard]] friend constexpr rectangle operator+(rectangle const& lhs, extent2 rhs) noexcept
209 {
210 hilet extra_right = normalize(lhs.right) * rhs.width();
211 hilet extra_up = normalize(lhs.up) * rhs.height();
212 hilet extra_diagonal = extra_right + extra_up;
213
214 return rectangle{lhs.origin - extra_diagonal, lhs.right + 2.0f * extra_right, lhs.up + 2.0f * extra_up};
215 }
216
230 [[nodiscard]] friend constexpr rectangle operator-(rectangle const& lhs, extent2 rhs) noexcept
231 {
232 hilet extra_right = normalize(lhs.right) * rhs.width();
233 hilet extra_up = normalize(lhs.up) * rhs.height();
234 hilet extra_diagonal = extra_right + extra_up;
235
236 return rectangle{lhs.origin + extra_diagonal, lhs.right - 2.0f * extra_right, lhs.up - 2.0f * extra_up};
237 }
238
252 [[nodiscard]] friend constexpr rectangle operator+(rectangle const& lhs, float rhs) noexcept
253 {
254 return lhs + extent2{rhs, rhs};
255 };
256
270 [[nodiscard]] friend constexpr rectangle operator-(rectangle const& lhs, float rhs) noexcept
271 {
272 return lhs - extent2{rhs, rhs};
273 }
274};
275
276}} // namespace hi::v1
types and utilities for alignment.
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:279
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:26
A high-level geometric extent.
Definition extent2.hpp:26
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent2.hpp:101
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent2.hpp:112
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
constexpr bool is_axis_aligned() const noexcept
Check if this is an axis aligned rectangle.
Definition rectangle.hpp:132
float height() const noexcept
The height, or length of the up vector.
Definition rectangle.hpp:147
friend constexpr rectangle operator-(rectangle const &lhs, float rhs) noexcept
Shrink the rectangle by subtracting an absolute distance from each side.
Definition rectangle.hpp:270
friend constexpr rectangle operator-(rectangle const &lhs, extent2 rhs) noexcept
Shrink the rectangle by subtracting an absolute distance from each side.
Definition rectangle.hpp:230
friend constexpr rectangle operator+(rectangle const &lhs, extent2 rhs) noexcept
Expand the rectangle by adding an absolute distance on each side.
Definition rectangle.hpp:208
friend constexpr rectangle operator+(rectangle const &lhs, float rhs) noexcept
Expand the rectangle by adding an absolute distance on each side.
Definition rectangle.hpp:252
constexpr rectangle(point3 origin, point3 right_bottom, point3 left_top, point3 right_top) noexcept
Create a rectangle from 4 corner points.
Definition rectangle.hpp:47
float width() const noexcept
The width, or length of the right vector.
Definition rectangle.hpp:140
constexpr extent2 size() const noexcept
The size, or length of the right and up vectors.
Definition rectangle.hpp:154
constexpr bool is_rectangle() const noexcept
Check if this is a rectangle.
Definition rectangle.hpp:122
constexpr rectangle(point3 origin, vector3 right, vector3 up) noexcept
Create a rectangle from a corner point and two vectors.
Definition rectangle.hpp:38
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector3.hpp:19
T right(T... args)
T min(T... args)