HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
scale.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 "matrix.hpp"
8#include "identity.hpp"
9#include "translate.hpp"
10#include "extent.hpp"
11
12namespace hi::inline v1 {
13namespace geo {
14
15template<int D>
16class scale {
17public:
18 static_assert(D == 2 || D == 3, "Only 2D or 3D scale-matrices are supported");
19
20 constexpr scale(scale const&) noexcept = default;
21 constexpr scale(scale&&) noexcept = default;
22 constexpr scale& operator=(scale const&) noexcept = default;
23 constexpr scale& operator=(scale&&) noexcept = default;
24
25 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
26 {
27 hi_axiom(holds_invariant());
28 return _v;
29 }
30
31 [[nodiscard]] constexpr explicit operator extent<float, 2>() const noexcept
32 requires(D == 2)
33 {
34 return extent<2>{_v.xy00()};
35 }
36
37 [[nodiscard]] constexpr explicit operator extent<float, 3>() const noexcept
38 requires(D == 3)
39 {
40 return extent<3>{_v.xyz0()};
41 }
42
43 [[nodiscard]] constexpr explicit scale(f32x4 const& v) noexcept : _v(v)
44 {
45 hi_axiom(holds_invariant());
46 }
47
48 template<int E>
49 requires(E <= D)
50 [[nodiscard]] constexpr explicit scale(vector<float, E> const& v) noexcept : _v(static_cast<f32x4>(v).xyz1())
51 {
52 hi_axiom(holds_invariant());
53 }
54
55 [[nodiscard]] constexpr operator matrix<D>() const noexcept
56 {
57 hi_axiom(holds_invariant());
58 return matrix<D>{_v.x000(), _v._0y00(), _v._00z0(), _v._000w()};
59 }
60
61 [[nodiscard]] constexpr scale() noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
62
63 [[nodiscard]] constexpr scale(identity const&) noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
64
65 [[nodiscard]] constexpr scale(float value) noexcept
66 requires(D == 2)
67 : _v(value, value, 1.0, 1.0)
68 {
69 }
70
71 [[nodiscard]] constexpr scale(float value) noexcept
72 requires(D == 3)
73 : _v(value, value, value, 1.0)
74 {
75 }
76
77 [[nodiscard]] constexpr scale(float x, float y) noexcept
78 requires(D == 2)
79 : _v(x, y, 1.0, 1.0)
80 {
81 }
82
83 [[nodiscard]] constexpr scale(float x, float y, float z = 1.0) noexcept
84 requires(D == 3)
85 : _v(x, y, z, 1.0)
86 {
87 }
88
94 template<int E>
95 [[nodiscard]] static constexpr scale uniform(extent<float, E> src, extent<float, E> dst) noexcept
96 requires(E <= D)
97 {
98 hi_axiom(dst.width() != 0.0f && src.width() != 0.0f && dst.height() != 0.0f && src.height() != 0.0f);
99
100 if constexpr (D == 2) {
101 hilet non_uniform_scale = static_cast<f32x4>(dst).xyxy() / static_cast<f32x4>(src).xyxy();
102 hilet uniform_scale = std::min(non_uniform_scale.x(), non_uniform_scale.y());
103 return scale{uniform_scale};
104
105 } else if constexpr (D == 3) {
106 hi_axiom(dst.z() != 0.0f && src.z() != 0.0f);
107 hilet non_uniform_scale = static_cast<f32x4>(dst).xyzx() / static_cast<f32x4>(src).xyzx();
108 hilet uniform_scale = std::min({non_uniform_scale.x(), non_uniform_scale.y(), non_uniform_scale.z()});
109 return scale{uniform_scale};
110
111 } else {
113 }
114 }
115
121 template<different_from<float> O, int E>
122 [[nodiscard]] static constexpr scale uniform(extent<O, E> src, extent<O, E> dst) noexcept
123 requires(E <= D)
124 {
125 return uniform(narrow_cast<extent<float, E>>(src), narrow_cast<extent<float, E>>(dst));
126 }
127
128 template<int E>
129 [[nodiscard]] constexpr vector<float, E> operator*(vector<float, E> const& rhs) const noexcept
130 {
131 hi_axiom(holds_invariant() && rhs.holds_invariant());
132 return vector<float, E>{_v * static_cast<f32x4>(rhs)};
133 }
134
135 template<int E>
136 [[nodiscard]] constexpr extent<float, E> operator*(extent<float, E> const& rhs) const noexcept
137 {
138 hi_axiom(holds_invariant() && rhs.holds_invariant());
139 return extent<float, E>{_v * static_cast<f32x4>(rhs)};
140 }
141
142 template<int E>
143 [[nodiscard]] constexpr point<float, E> operator*(point<float, E> const& rhs) const noexcept
144 {
145 hi_axiom(holds_invariant() && rhs.holds_invariant());
146 return point<float, E>{_v * static_cast<f32x4>(rhs)};
147 }
148
151 [[nodiscard]] constexpr aarectangle operator*(aarectangle const& rhs) const noexcept
152 requires(D == 2)
153 {
154 return aarectangle{*this * get<0>(rhs), *this * get<3>(rhs)};
155 }
156
157 [[nodiscard]] constexpr rectangle operator*(rectangle const& rhs) const noexcept
158 {
159 return rectangle{*this * get<0>(rhs), *this * get<1>(rhs), *this * get<2>(rhs), *this * get<3>(rhs)};
160 }
161
162 [[nodiscard]] constexpr quad operator*(quad const& rhs) const noexcept
163 {
164 return quad{*this * rhs.p0, *this * rhs.p1, *this * rhs.p2, *this * rhs.p3};
165 }
166
175 [[nodiscard]] friend constexpr quad scale_from_center(quad const& lhs, scale const& rhs) noexcept
176 requires(D == 2)
177 {
178 hilet top_extra = (lhs.top() * rhs._v.x() - lhs.top()) * 0.5f;
179 hilet bottom_extra = (lhs.bottom() * rhs._v.x() - lhs.bottom()) * 0.5f;
180 hilet left_extra = (lhs.left() * rhs._v.y() - lhs.left()) * 0.5f;
181 hilet right_extra = (lhs.right() * rhs._v.y() - lhs.right()) * 0.5f;
182
183 return {
184 lhs.p0 - bottom_extra - left_extra,
185 lhs.p1 + bottom_extra - right_extra,
186 lhs.p2 - top_extra + left_extra,
187 lhs.p3 + top_extra + right_extra};
188 }
189
190 [[nodiscard]] constexpr scale operator*(identity const&) const noexcept
191 {
192 hi_axiom(holds_invariant());
193 return *this;
194 }
195
196 template<int E>
197 [[nodiscard]] constexpr auto operator*(scale<E> const& rhs) const noexcept
198 {
199 hi_axiom(holds_invariant() && rhs.holds_invariant());
200 return scale<std::max(D, E)>{_v * static_cast<f32x4>(rhs)};
201 }
202
203 template<int E>
204 [[nodiscard]] constexpr bool operator==(scale<E> const& rhs) const noexcept
205 {
206 hi_axiom(holds_invariant() && rhs.holds_invariant());
207 return equal(_v, static_cast<f32x4>(rhs));
208 }
209
210 [[nodiscard]] constexpr bool holds_invariant() const noexcept
211 {
212 if constexpr (D == 3) {
213 return _v.w() == 1.0f;
214 } else {
215 return _v.z() == 1.0f and _v.w() == 1.0f;
216 }
217 }
218
219private:
220 f32x4 _v;
221};
222
223[[nodiscard]] constexpr scale<2> operator/(extent<float, 2> const& lhs, extent<float, 2> const& rhs) noexcept
224{
225 hi_axiom(rhs._v.x() != 0.0f);
226 hi_axiom(rhs._v.y() != 0.0f);
227 return scale<2>{lhs._v.xy11() / rhs._v.xy11()};
228}
229
230[[nodiscard]] constexpr scale<3> operator/(extent<float, 3> const& lhs, extent<float, 3> const& rhs) noexcept
231{
232 hi_axiom(rhs._v.x() != 0.0f);
233 hi_axiom(rhs._v.y() != 0.0f);
234 hi_axiom(rhs._v.z() != 0.0f);
235 return scale<3>{lhs._v.xyz1() / rhs._v.xyz1()};
236}
237
238template<int D>
239[[nodiscard]] constexpr matrix<D>
240matrix<D>::uniform(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
241{
242 hilet scale = hi::geo::scale<D>::uniform(src_rectangle.size(), dst_rectangle.size());
243 hilet scaled_rectangle = scale * src_rectangle;
244 hilet translation = translate<D>::align(scaled_rectangle, dst_rectangle, alignment);
245 return translation * scale;
246}
247
248} // namespace geo
249
250using scale2 = geo::scale<2>;
251using scale3 = geo::scale<3>;
252
253} // namespace hi::inline v1
Defines identity type.
Defined the geo::extent, extent2 and extent3 types.
Defines geo::matrix, matrix2 and matrix3.
#define hi_static_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:323
#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
DOXYGEN BUG.
Definition algorithm.hpp:13
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:367
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:27
Definition extent.hpp:20
A 2D or 3D homogenius matrix for transforming homogenious vectors and points.
Definition matrix.hpp:33
Definition quad.hpp:17
point3 p0
Left-bottom.
Definition quad.hpp:19
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
Definition scale.hpp:16
constexpr aarectangle operator*(aarectangle const &rhs) const noexcept
Scale a rectangle around it's center.
Definition scale.hpp:151
static constexpr scale uniform(extent< O, E > src, extent< O, E > dst) noexcept
Get a uniform-scale-transform to scale an extent to another extent.
Definition scale.hpp:122
friend constexpr quad scale_from_center(quad const &lhs, scale const &rhs) noexcept
scale the quad.
Definition scale.hpp:175
static constexpr scale uniform(extent< float, E > src, extent< float, E > dst) noexcept
Get a uniform-scale-transform to scale an extent to another extent.
Definition scale.hpp:95
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 min(T... args)