9#include "translate.hpp"
12namespace hi::inline
v1 {
18 static_assert(D == 2 || D == 3,
"Only 2D or 3D scale-matrices are supported");
20 constexpr scale(
scale const &)
noexcept =
default;
22 constexpr scale &operator=(
scale const &)
noexcept =
default;
23 constexpr scale &operator=(
scale &&)
noexcept =
default;
25 [[nodiscard]]
constexpr explicit operator f32x4()
const noexcept
31 [[nodiscard]]
constexpr explicit operator extent<2>()
const noexcept requires(D == 2)
36 [[nodiscard]]
constexpr explicit operator extent<3>()
const noexcept requires(D == 3)
41 [[nodiscard]]
constexpr explicit scale(
f32x4 const &v) noexcept : _v(v)
47 requires(E <= D) [[nodiscard]]
constexpr explicit scale(
vector<E> const &v) noexcept : _v(
static_cast<f32x4>(v).xyz1())
52 [[nodiscard]]
constexpr operator matrix<D>()
const noexcept
55 return matrix<D>{_v.x000(), _v._0y00(), _v._00z0(), _v._000w()};
58 [[nodiscard]]
constexpr scale() noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
60 [[nodiscard]]
constexpr scale(identity
const &) noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
62 [[nodiscard]]
constexpr scale(
float value)
noexcept requires(D == 2) : _v(value, value, 1.0, 1.0) {}
64 [[nodiscard]]
constexpr scale(
float value)
noexcept requires(D == 3) : _v(value, value, value, 1.0) {}
66 [[nodiscard]]
constexpr scale(
float x,
float y)
noexcept requires(D == 2) : _v(x, y, 1.0, 1.0) {}
68 [[nodiscard]]
constexpr scale(
float x,
float y,
float z = 1.0)
noexcept requires(D == 3) : _v(x, y, z, 1.0) {}
75 template<
int E,
int F>
79 dst_extent.
width() != 0.0f && src_extent.
width() != 0.0f && dst_extent.
height() != 0.0f &&
80 src_extent.
height() != 0.0f);
82 if constexpr (D == 2) {
83 hilet non_uniform_scale =
static_cast<f32x4>(dst_extent).xyxy() /
static_cast<f32x4>(src_extent).xyxy();
84 hilet uniform_scale =
std::min(non_uniform_scale.x(), non_uniform_scale.y());
85 return scale{uniform_scale};
87 }
else if constexpr (D == 3) {
88 hi_axiom(dst_extent.z() != 0.0f && src_extent.z() != 0.0f);
89 hilet non_uniform_scale =
static_cast<f32x4>(dst_extent).xyzx() /
static_cast<f32x4>(src_extent).xyzx();
90 hilet uniform_scale =
std::min({non_uniform_scale.x(), non_uniform_scale.y(), non_uniform_scale.z()});
91 return scale{uniform_scale};
101 hi_axiom(holds_invariant() && rhs.holds_invariant());
106 [[nodiscard]]
constexpr extent<E> operator*(extent<E>
const &rhs)
const noexcept
108 hi_axiom(holds_invariant() && rhs.holds_invariant());
109 return extent<E>{_v *
static_cast<f32x4
>(rhs)};
113 [[nodiscard]]
constexpr point<E> operator*(point<E>
const &rhs)
const noexcept
115 hi_axiom(holds_invariant() && rhs.holds_invariant());
116 return point<E>{_v *
static_cast<f32x4
>(rhs)};
123 return aarectangle{*
this * get<0>(rhs), *
this * get<3>(rhs)};
128 return rectangle{*
this * get<0>(rhs), *
this * get<1>(rhs), *
this * get<2>(rhs), *
this * get<3>(rhs)};
131 [[nodiscard]]
constexpr quad operator*(
quad const &rhs)
const noexcept
133 return quad{*
this * rhs.
p0, *
this * rhs.p1, *
this * rhs.p2, *
this * rhs.p3};
146 hilet top_extra = (lhs.top() * rhs._v.x() - lhs.top()) * 0.5f;
147 hilet bottom_extra = (lhs.bottom() * rhs._v.x() - lhs.bottom()) * 0.5f;
148 hilet left_extra = (lhs.left() * rhs._v.y() - lhs.left()) * 0.5f;
149 hilet right_extra = (lhs.right() * rhs._v.y() - lhs.right()) * 0.5f;
152 lhs.
p0 - bottom_extra - left_extra,
153 lhs.p1 + bottom_extra - right_extra,
154 lhs.p2 - top_extra + left_extra,
155 lhs.p3 + top_extra + right_extra};
158 [[nodiscard]]
constexpr scale operator*(identity
const &)
const noexcept
165 [[nodiscard]]
constexpr auto operator*(scale<E>
const &rhs)
const noexcept
167 hi_axiom(holds_invariant() && rhs.holds_invariant());
172 [[nodiscard]]
constexpr bool operator==(scale<E>
const &rhs)
const noexcept
174 hi_axiom(holds_invariant() && rhs.holds_invariant());
175 return _v ==
static_cast<f32x4
>(rhs);
178 [[nodiscard]]
constexpr bool holds_invariant() const noexcept
180 if constexpr (D == 3) {
181 return _v.w() == 1.0f;
183 return _v.z() == 1.0f and _v.w() == 1.0f;
191[[nodiscard]]
constexpr scale<2> operator/(extent<2>
const &lhs, extent<2>
const &rhs)
noexcept
195 return scale<2>{lhs._v.xy11() / rhs._v.xy11()};
198[[nodiscard]]
constexpr scale<3> operator/(extent<3>
const &lhs, extent<3>
const &rhs)
noexcept
203 return scale<3>{lhs._v.xyz1() / rhs._v.xyz1()};
207[[nodiscard]]
constexpr matrix<D>
210 hilet scale = hi::geo::scale<D>::uniform(src_rectangle.size(), dst_rectangle.size());
211 hilet scaled_rectangle =
scale * src_rectangle;
213 return translation *
scale;
#define hi_axiom(expression)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
#define hi_static_no_default()
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:172
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
Definition alignment.hpp:75
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
constexpr aarectangle operator*(aarectangle const &rhs) const noexcept
Scale a rectangle around it's center.
Definition scale.hpp:121
friend constexpr quad scale_from_center(quad const &lhs, scale const &rhs) noexcept
scale the quad.
Definition scale.hpp:144
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:76
A high-level geometric extent.
Definition extent.hpp:23
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent.hpp:151
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent.hpp:140
point3 p0
Left-bottom.
Definition quad.hpp:19
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
Definition translate.hpp:15
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:21