HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
translate.hpp
1// Copyright Take Vos 2021.
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 "matrix.hpp"
8#include "identity.hpp"
9#include "rotate.hpp"
10
11namespace hi::inline v1 {
12namespace geo {
13
14template<int D>
15class translate {
16public:
17 static_assert(D == 2 || D == 3, "Only 2D or 3D translation-matrices are supported");
18
19 constexpr translate(translate const &) noexcept = default;
20 constexpr translate(translate &&) noexcept = default;
21 constexpr translate &operator=(translate const &) noexcept = default;
22 constexpr translate &operator=(translate &&) noexcept = default;
23
24 [[nodiscard]] constexpr operator matrix<2>() const noexcept requires(D == 2)
25 {
26 hi_axiom(holds_invariant());
27 hilet ones = f32x4::broadcast(1.0);
28 return matrix<2>{ones.x000(), ones._0y00(), ones._00z0(), ones._000w() + _v};
29 }
30
31 [[nodiscard]] constexpr operator matrix<3>() const noexcept
32 {
33 hi_axiom(holds_invariant());
34 hilet ones = f32x4::broadcast(1.0);
35 return matrix<3>{ones.x000(), ones._0y00(), ones._00z0(), ones._000w() + _v};
36 }
37
38 [[nodiscard]] constexpr translate() noexcept : _v() {}
39
40 [[nodiscard]] constexpr translate(identity const &) noexcept : translate() {}
41
42 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
43 {
44 hi_axiom(holds_invariant());
45 return _v;
46 }
47
48 [[nodiscard]] constexpr explicit translate(f32x4 const &other) noexcept : _v(other)
49 {
50 hi_axiom(holds_invariant());
51 }
52
53 [[nodiscard]] constexpr explicit translate(aarectangle const &other) noexcept : _v(static_cast<f32x4>(get<0>(other)).xy00())
54 {
55 hi_axiom(holds_invariant());
56 }
57
58 [[nodiscard]] constexpr explicit translate(aarectangle const &other, float z) noexcept requires(D == 3) :
59 _v(static_cast<f32x4>(get<0>(other)).xy00())
60 {
61 _v.z() = z;
62 hi_axiom(holds_invariant());
63 }
64
65 template<int E>
66 requires(E < D) [[nodiscard]] constexpr translate(translate<E> const &other) noexcept : _v(static_cast<f32x4>(other))
67 {
68 hi_axiom(holds_invariant());
69 }
70
71 template<int E>
72 requires(E <= D) [[nodiscard]] constexpr explicit translate(vector<E> const &other) noexcept : _v(static_cast<f32x4>(other))
73 {
74 hi_axiom(holds_invariant());
75 }
76
77 template<int E>
78 requires(E <= D) [[nodiscard]] constexpr explicit translate(point<E> const &other) noexcept :
79 _v(static_cast<f32x4>(other).xyz0())
80 {
81 hi_axiom(holds_invariant());
82 }
83
84 [[nodiscard]] constexpr translate(float x, float y) noexcept requires(D == 2) : _v(x, y, 0.0, 0.0) {}
85
86 [[nodiscard]] constexpr translate(float x, float y, float z = 0.0) noexcept requires(D == 3) : _v(x, y, z, 0.0) {}
87
94 [[nodiscard]] constexpr static translate
95 align(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
96 {
97 auto x = 0.0f;
98 if (alignment == horizontal_alignment::left) {
99 x = dst_rectangle.left();
100
101 } else if (alignment == horizontal_alignment::right) {
102 x = dst_rectangle.right() - src_rectangle.width();
103
104 } else if (alignment == horizontal_alignment::center) {
105 x = dst_rectangle.center() - src_rectangle.width() * 0.5f;
106
107 } else {
108 hi_no_default();
109 }
110
111 auto y = 0.0f;
112 if (alignment == vertical_alignment::bottom) {
113 y = dst_rectangle.bottom();
114
115 } else if (alignment == vertical_alignment::top) {
116 y = dst_rectangle.top() - src_rectangle.height();
117
118 } else if (alignment == vertical_alignment::middle) {
119 y = dst_rectangle.middle() - src_rectangle.height() * 0.5f;
120
121 } else {
122 hi_no_default();
123 }
124
125 return translate{x - src_rectangle.left(), y - src_rectangle.bottom()};
126 }
127
128 template<int E>
129 [[nodiscard]] constexpr vector<E> operator*(vector<E> const &rhs) const noexcept
130 {
131 // Vectors are not translated.
132 hi_axiom(holds_invariant() && rhs.holds_invariant());
133 return rhs;
134 }
135
136 template<int E>
137 [[nodiscard]] constexpr point<std::max(D, E)> operator*(point<E> const &rhs) const noexcept
138 {
139 hi_axiom(holds_invariant() && rhs.holds_invariant());
140 return point<std::max(D, E)>{_v + static_cast<f32x4>(rhs)};
141 }
142
143 [[nodiscard]] constexpr aarectangle operator*(aarectangle const &rhs) const noexcept requires(D == 2)
144 {
145 return aarectangle{*this * get<0>(rhs), *this * get<3>(rhs)};
146 }
147
148 [[nodiscard]] constexpr rectangle operator*(aarectangle const &rhs) const noexcept requires(D == 3)
149 {
150 return *this * rectangle{rhs};
151 }
152
153 [[nodiscard]] constexpr rectangle operator*(rectangle const &rhs) const noexcept
154 {
155 return rectangle{*this * rhs.origin, rhs.right, rhs.up};
156 }
157
158 [[nodiscard]] constexpr quad operator*(quad const &rhs) const noexcept
159 {
160 return quad{*this * rhs.p0, *this * rhs.p1, *this * rhs.p2, *this * rhs.p3};
161 }
162
163 [[nodiscard]] constexpr circle operator*(circle const &rhs) const noexcept
164 {
165 return circle{f32x4{rhs} + _v};
166 }
167
168 [[nodiscard]] constexpr line_segment operator*(line_segment const &rhs) const noexcept
169 {
170 return line_segment{*this * rhs.origin(), rhs.direction()};
171 }
172
173 [[nodiscard]] constexpr translate operator*(identity const &) const noexcept
174 {
175 hi_axiom(holds_invariant());
176 return *this;
177 }
178
179 template<int E>
180 [[nodiscard]] constexpr auto operator*(matrix<E> const &rhs) const noexcept
181 {
182 hi_axiom(holds_invariant() && rhs.holds_invariant());
183 return matrix<std::max(D, E)>{get<0>(rhs), get<1>(rhs), get<2>(rhs), get<3>(rhs) + _v};
184 }
185
186 template<int E>
187 [[nodiscard]] constexpr auto operator*(rotate<E> const &rhs) const noexcept
188 {
189 return *this * matrix<E>(rhs);
190 }
191
192 template<int E>
193 [[nodiscard]] constexpr auto operator*(translate<E> const &rhs) const noexcept
194 {
195 hi_axiom(holds_invariant() && rhs.holds_invariant());
196 return translate<std::max(D, E)>{_v + static_cast<f32x4>(rhs)};
197 }
198
199 template<int E>
200 [[nodiscard]] constexpr bool operator==(translate<E> const &rhs) const noexcept
201 {
202 hi_axiom(holds_invariant() && rhs.holds_invariant());
203 return _v == static_cast<f32x4>(rhs);
204 }
205
206 [[nodiscard]] constexpr translate operator~() const noexcept
207 {
208 return translate{-_v};
209 }
210
211 [[nodiscard]] constexpr bool holds_invariant() const noexcept
212 {
213 return _v.w() == 0.0f && (D == 3 || _v.z() == 0.0f);
214 }
215
216 [[nodiscard]] friend constexpr translate round(translate const &rhs) noexcept
217 {
218 return translate{round(rhs._v)};
219 }
220
221private:
222 f32x4 _v;
223};
224
225} // namespace geo
226
227using translate2 = geo::translate<2>;
228using translate3 = geo::translate<3>;
229
230constexpr translate3 translate_z(float z) noexcept
231{
232 return translate3{0.0f, 0.0f, z};
233}
234
235} // namespace hi::inline v1
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Definition alignment.hpp:64
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
Definition identity.hpp:11
Definition matrix.hpp:22
A high-level geometric point Part of the high-level vec, point, mat and color types.
Definition point.hpp:23
Definition translate.hpp:15
static constexpr translate align(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition translate.hpp:95
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:20
T max(T... args)
T round(T... args)