HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
scale.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 "translate.hpp"
10
11namespace tt {
12namespace geo {
13
14template<int D>
15class scale {
16public:
17 static_assert(D == 2 || D == 3, "Only 2D or 3D scale-matrices are supported");
18
19 constexpr scale(scale const &) noexcept = default;
20 constexpr scale(scale &&) noexcept = default;
21 constexpr scale &operator=(scale const &) noexcept = default;
22 constexpr scale &operator=(scale &&) noexcept = default;
23
24 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
25 {
26 tt_axiom(is_valid());
27 return _v;
28 }
29
30 [[nodiscard]] constexpr explicit scale(f32x4 const &v) noexcept : _v(v)
31 {
32 tt_axiom(is_valid());
33 }
34
35 template<int E>
36 requires(E <= D) [[nodiscard]] constexpr explicit scale(vector<E> const &v) noexcept : _v(static_cast<f32x4>(v).xyz1())
37 {
38 tt_axiom(is_valid());
39 }
40
41 [[nodiscard]] constexpr operator matrix<D>() const noexcept
42 {
43 tt_axiom(is_valid());
44 return matrix<D>{_v.x000(), _v._0y00(), _v._00z0(), _v._000w()};
45 }
46
47 [[nodiscard]] constexpr scale() noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
48
49 [[nodiscard]] constexpr scale(identity const &) noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
50
51 [[nodiscard]] constexpr scale(float value) noexcept requires(D == 2) : _v(value, value, 1.0, 1.0) {}
52
53 [[nodiscard]] constexpr scale(float value) noexcept requires(D == 3) : _v(value, value, value, 1.0) {}
54
55 [[nodiscard]] constexpr scale(float x, float y) noexcept requires(D == 2) : _v(x, y, 1.0, 1.0) {}
56
57 [[nodiscard]] constexpr scale(float x, float y, float z = 1.0) noexcept requires(D == 3) : _v(x, y, z, 1.0) {}
58
64 template<int E, int F>
65 requires(E <= D && F <= D) [[nodiscard]] static constexpr scale uniform(extent<E> src_extent, extent<F> dst_extent) noexcept
66 {
67 tt_axiom(
68 dst_extent.width() != 0.0f && src_extent.width() != 0.0f && dst_extent.height() != 0.0f &&
69 src_extent.height() != 0.0f);
70
71 if constexpr (D == 2) {
72 ttlet non_uniform_scale = static_cast<f32x4>(dst_extent).xyxy() / static_cast<f32x4>(src_extent).xyxy();
73 ttlet uniform_scale = std::min(non_uniform_scale.x(), non_uniform_scale.y());
74 return scale{uniform_scale};
75
76 } else if constexpr (D == 3) {
77 tt_axiom(dst_extent.z() != 0.0f && src_extent.z() != 0.0f);
78 ttlet non_uniform_scale = static_cast<f32x4>(dst_extent).xyzx() / static_cast<f32x4>(src_extent).xyzx();
79 ttlet uniform_scale = std::min({non_uniform_scale.x(), non_uniform_scale.y(), non_uniform_scale.z()});
80 return scale{uniform_scale};
81
82 } else {
83 tt_static_no_default();
84 }
85 }
86
87 template<int E>
88 [[nodiscard]] constexpr vector<E> operator*(vector<E> const &rhs) const noexcept
89 {
90 tt_axiom(is_valid() && rhs.is_valid());
91 return vector<E>{_v * static_cast<f32x4>(rhs)};
92 }
93
94 template<int E>
95 [[nodiscard]] constexpr extent<E> operator*(extent<E> const &rhs) const noexcept
96 {
97 tt_axiom(is_valid() && rhs.is_valid());
98 return extent<E>{_v * static_cast<f32x4>(rhs)};
99 }
100
101 template<int E>
102 [[nodiscard]] constexpr point<E> operator*(point<E> const &rhs) const noexcept
103 {
104 tt_axiom(is_valid() && rhs.is_valid());
105 return point<E>{_v * static_cast<f32x4>(rhs)};
107
110 [[nodiscard]] constexpr aarectangle operator*(aarectangle const &rhs) const noexcept requires(D == 2)
111 {
112 return aarectangle{*this * get<0>(rhs), *this * get<3>(rhs)};
113 }
114
115 [[nodiscard]] constexpr rectangle operator*(rectangle const &rhs) const noexcept
116 {
117 return rectangle{*this * get<0>(rhs), *this * get<1>(rhs), *this * get<2>(rhs), *this * get<3>(rhs)};
118 }
119
120 [[nodiscard]] constexpr scale operator*(identity const &) const noexcept
121 {
122 tt_axiom(is_valid());
123 return *this;
124 }
125
126 template<int E>
127 [[nodiscard]] constexpr auto operator*(scale<E> const &rhs) const noexcept
128 {
129 tt_axiom(is_valid() && rhs.is_valid());
130 return scale<std::max(D, E)>{_v * static_cast<f32x4>(rhs)};
131 }
132
133 template<int E>
134 [[nodiscard]] constexpr bool operator==(scale<E> const &rhs) const noexcept
135 {
136 tt_axiom(is_valid() && rhs.is_valid());
137 return _v == static_cast<f32x4>(rhs);
138 }
139
140 [[nodiscard]] constexpr bool is_valid() const noexcept
141 {
142 return _v.w() == 1.0f && (D == 3 || _v.z() == 1.0f);
143 }
144
145private:
146 f32x4 _v;
147};
148
149template<int D>
150[[nodiscard]] constexpr matrix<D>
151matrix<D>::uniform(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
152{
153 ttlet scale = tt::geo::scale<D>::uniform(src_rectangle.size(), dst_rectangle.size());
154 ttlet scaled_rectangle = scale * src_rectangle;
155 ttlet translation = translate<D>::align(scaled_rectangle, dst_rectangle, alignment);
156 return translation * scale;
157}
158
159} // namespace geo
160
161using scale2 = geo::scale<2>;
162using scale3 = geo::scale<3>;
163
164} // namespace tt
alignment
Vertical and horizontal alignment.
Definition alignment.hpp:47
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
A high-level geometric extent.
Definition extent.hpp:20
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent.hpp:142
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent.hpp:153
Definition identity.hpp:11
Definition matrix.hpp:18
static constexpr matrix uniform(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
Create a transformation matrix to translate and uniformly-scale a src_rectangle to a dst_rectangle.
Definition scale.hpp:151
Class which represents an rectangle.
Definition rectangle.hpp:16
Definition scale.hpp:15
constexpr aarectangle operator*(aarectangle const &rhs) const noexcept
Scale a rectangle around it's center.
Definition scale.hpp:110
static constexpr scale uniform(extent< E > src_extent, extent< F > dst_extent) noexcept
Get a uniform-scale-transform to scale an extent to another extent.
Definition scale.hpp:65
static constexpr translate align(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition translate.hpp:87
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 min(T... args)