HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
translate.hpp
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version value_type{1}.
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 "matrix.hpp"
8#include "identity.hpp"
9#include "rotate.hpp"
10
11namespace hi::inline v1 {
12namespace geo {
13
14template<typename T, int D>
15class translate {
16public:
17 static_assert(D == 2 || D == 3, "Only 2D or 3D translation-matrices are supported");
18
19 using value_type = T;
20 using array_type = simd<value_type, 4>;
21
22 constexpr translate(translate const&) noexcept = default;
23 constexpr translate(translate&&) noexcept = default;
24 constexpr translate& operator=(translate const&) noexcept = default;
25 constexpr translate& operator=(translate&&) noexcept = default;
26
27 [[nodiscard]] constexpr operator matrix<2>() const noexcept
28 requires std::is_same_v<value_type, float> and (D == 2)
29 {
30 hi_axiom(holds_invariant());
31 hilet ones = array_type::broadcast(value_type{1});
32 return matrix<2>{ones.x000(), ones._0y00(), ones._00z0(), ones._000w() + _v};
33 }
34
35 [[nodiscard]] constexpr operator matrix<3>() const noexcept
36 requires std::is_same_v<value_type, float>
37 {
38 hi_axiom(holds_invariant());
39 hilet ones = array_type::broadcast(value_type{1});
40 return matrix<3>{ones.x000(), ones._0y00(), ones._00z0(), ones._000w() + _v};
41 }
42
43 [[nodiscard]] constexpr translate() noexcept : _v() {}
44
45 [[nodiscard]] constexpr translate(identity const&) noexcept : translate() {}
46
47 [[nodiscard]] constexpr explicit operator array_type() const noexcept
48 {
49 hi_axiom(holds_invariant());
50 return _v;
51 }
52
53 [[nodiscard]] constexpr explicit translate(array_type const& other) noexcept : _v(other)
54 {
55 hi_axiom(holds_invariant());
56 }
57
58 [[nodiscard]] constexpr explicit translate(axis_aligned_rectangle const& other) noexcept :
59 _v(static_cast<array_type>(get<0>(other)).xy00())
60 {
61 hi_axiom(holds_invariant());
62 }
63
64 [[nodiscard]] constexpr explicit translate(axis_aligned_rectangle const& other, value_type z) noexcept
65 requires(D == 3)
66 : _v(static_cast<array_type>(get<0>(other)).xy00())
67 {
68 _v.z() = z;
69 hi_axiom(holds_invariant());
70 }
71
72 template<int E>
73 requires(E < D)
74 [[nodiscard]] constexpr translate(translate<value_type, E> const& other) noexcept : _v(static_cast<array_type>(other))
75 {
76 hi_axiom(holds_invariant());
77 }
78
79 template<int E>
80 requires(E < D)
81 [[nodiscard]] constexpr translate(translate<value_type, E> const& other, value_type z) noexcept :
82 _v(static_cast<array_type>(other))
83 {
84 _v.z() = z;
85 hi_axiom(holds_invariant());
86 }
87
88 template<int E>
89 requires(E <= D)
90 [[nodiscard]] constexpr explicit translate(vector<value_type, E> const& other) noexcept : _v(static_cast<array_type>(other))
91 {
92 hi_axiom(holds_invariant());
93 }
94
95 template<int E>
96 requires(E <= D)
97 [[nodiscard]] constexpr explicit translate(point<value_type, E> const& other) noexcept :
98 _v(static_cast<array_type>(other).xyz0())
99 {
100 hi_axiom(holds_invariant());
101 }
102
103 [[nodiscard]] constexpr translate(value_type x, value_type y) noexcept
104 requires(D == 2)
105 : _v(x, y, value_type{0}, value_type{0})
106 {
107 }
108
109 [[nodiscard]] constexpr translate(value_type x, value_type y, value_type z = value_type{0}) noexcept
110 requires(D == 3)
111 : _v(x, y, z, value_type{0})
112 {
113 }
114
115 [[nodiscard]] constexpr value_type x() const noexcept
116 {
117 return _v.x();
118 }
119
120 [[nodiscard]] constexpr value_type y() const noexcept
121 requires(D >= 2)
122 {
123 return _v.y();
124 }
125
126 [[nodiscard]] constexpr value_type z() const noexcept
127 requires(D >= 3)
128 {
129 return _v.z();
130 }
131
132 [[nodiscard]] constexpr value_type& x() noexcept
133 {
134 return _v.x();
135 }
136
137 [[nodiscard]] constexpr value_type& y() noexcept
138 requires(D >= 2)
139 {
140 return _v.y();
141 }
142
143 [[nodiscard]] constexpr value_type& z() noexcept
144 requires(D >= 3)
145 {
146 return _v.z();
147 }
148
155 [[nodiscard]] constexpr static translate align(
156 axis_aligned_rectangle src_rectangle,
157 axis_aligned_rectangle dst_rectangle,
158 alignment alignment) noexcept
159 {
160 auto x = value_type{0};
161 if (alignment == horizontal_alignment::left) {
162 x = dst_rectangle.left();
163
164 } else if (alignment == horizontal_alignment::right) {
165 x = dst_rectangle.right() - src_rectangle.width();
166
167 } else if (alignment == horizontal_alignment::center) {
168 x = dst_rectangle.center() - src_rectangle.width() * 0.5f;
169
170 } else {
172 }
173
174 auto y = value_type{0};
175 if (alignment == vertical_alignment::bottom) {
176 y = dst_rectangle.bottom();
177
178 } else if (alignment == vertical_alignment::top) {
179 y = dst_rectangle.top() - src_rectangle.height();
180
181 } else if (alignment == vertical_alignment::middle) {
182 y = dst_rectangle.middle() - src_rectangle.height() * 0.5f;
183
184 } else {
186 }
187
188 return translate{x - src_rectangle.left(), y - src_rectangle.bottom()};
189 }
190
191 template<int E>
192 [[nodiscard]] constexpr translate operator+(vector<value_type, E> const& rhs) const noexcept
193 {
194 return translate{_v + static_cast<array_type>(rhs)};
195 }
196
197 template<int E>
198 constexpr translate &operator+=(vector<value_type, E> const& rhs) noexcept
199 {
200 return *this = *this + rhs;
201 }
202
203 template<int E>
204 [[nodiscard]] constexpr vector<value_type, E> operator*(vector<value_type, E> const& rhs) const noexcept
205 {
206 // Vectors are not translated.
207 hi_axiom(holds_invariant() && rhs.holds_invariant());
208 return rhs;
209 }
210
211 template<int E>
212 [[nodiscard]] constexpr point<value_type, std::max(D, E)> operator*(point<value_type, E> const& rhs) const noexcept
213 {
214 hi_axiom(holds_invariant() && rhs.holds_invariant());
215 return point<value_type, std::max(D, E)>{_v + static_cast<array_type>(rhs)};
216 }
217
218 [[nodiscard]] constexpr axis_aligned_rectangle
219 operator*(axis_aligned_rectangle const& rhs) const noexcept
220 requires(D == 2)
221 {
222 return axis_aligned_rectangle{*this * get<0>(rhs), *this * get<3>(rhs)};
223 }
224
225 [[nodiscard]] constexpr rectangle operator*(axis_aligned_rectangle const& rhs) const noexcept
226 requires std::is_same_v<value_type, float> and (D == 3)
227 {
228 return *this * rectangle{rhs};
229 }
230
231 [[nodiscard]] constexpr rectangle operator*(rectangle const& rhs) const noexcept
232 requires std::is_same_v<value_type, float>
233 {
234 return rectangle{*this * rhs.origin, rhs.right, rhs.up};
235 }
236
237 [[nodiscard]] constexpr quad operator*(quad const& rhs) const noexcept
238 requires std::is_same_v<value_type, float>
239 {
240 return quad{*this * rhs.p0, *this * rhs.p1, *this * rhs.p2, *this * rhs.p3};
241 }
242
243 [[nodiscard]] constexpr circle operator*(circle const& rhs) const noexcept
244 requires std::is_same_v<value_type, float>
245 {
246 return circle{array_type{rhs} + _v};
247 }
248
249 [[nodiscard]] constexpr line_segment operator*(line_segment const& rhs) const noexcept
250 requires std::is_same_v<value_type, float>
251 {
252 return line_segment{*this * rhs.origin(), rhs.direction()};
253 }
254
255 [[nodiscard]] constexpr translate operator*(identity const&) const noexcept
256 {
257 hi_axiom(holds_invariant());
258 return *this;
259 }
260
261 template<int E>
262 [[nodiscard]] constexpr auto operator*(matrix<E> const& rhs) const noexcept
263 requires std::is_same_v<value_type, float>
264 {
265 hi_axiom(holds_invariant() && rhs.holds_invariant());
266 return matrix<std::max(D, E)>{get<0>(rhs), get<1>(rhs), get<2>(rhs), get<3>(rhs) + _v};
267 }
268
269 template<int E>
270 [[nodiscard]] constexpr auto operator*(rotate<E> const& rhs) const noexcept
271 requires std::is_same_v<value_type, float>
272 {
273 return *this * matrix<E>(rhs);
274 }
275
276 template<int E>
277 [[nodiscard]] constexpr auto operator*(translate<value_type, E> const& rhs) const noexcept
278 {
279 hi_axiom(holds_invariant() && rhs.holds_invariant());
280 return translate<value_type, std::max(D, E)>{_v + static_cast<array_type>(rhs)};
281 }
282
283 template<int E>
284 [[nodiscard]] constexpr bool operator==(translate<value_type, E> const& rhs) const noexcept
285 {
286 hi_axiom(holds_invariant() && rhs.holds_invariant());
287 return equal(_v, static_cast<array_type>(rhs));
288 }
289
290 [[nodiscard]] constexpr translate operator~() const noexcept
291 {
292 return translate{-_v};
293 }
294
295 [[nodiscard]] constexpr bool holds_invariant() const noexcept
296 {
297 return _v.w() == value_type{0} && (D == 3 || _v.z() == value_type{0});
298 }
299
300 [[nodiscard]] friend constexpr translate round(translate const& rhs) noexcept
301 requires std::is_same_v<value_type, float>
302 {
303 return translate{round(rhs._v)};
304 }
305
306private:
307 array_type _v;
308};
309
310} // namespace geo
311
312using translate2 = geo::translate<float, 2>;
313using translate3 = geo::translate<float, 3>;
314
315constexpr translate3 translate_z(float z) noexcept
316{
317 return translate3{float{0}, float{0}, z};
318}
319
320} // namespace hi::inline v1
Defines identity type.
Defines geo::matrix, matrix2 and matrix3.
#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
@ rectangle
The gui_event has rectangle data.
DOXYGEN BUG.
Definition algorithm.hpp:13
Horizontal/Vertical alignment combination.
Definition alignment.hpp:238
A high-level geometric point Part of the high-level vec, point, mat and color types.
Definition point.hpp:24
Definition translate.hpp:15
static constexpr translate align(axis_aligned_rectangle src_rectangle, axis_aligned_rectangle dst_rectangle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition translate.hpp:155
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:21
T equal(T... args)
T max(T... args)
T round(T... args)