lerp with two scale argumets

This commit is contained in:
BlackMATov
2021-01-31 01:41:29 +07:00
parent 006bd47ae6
commit 89f9872d96
4 changed files with 78 additions and 1 deletions

View File

@@ -26,6 +26,12 @@ namespace vmath_hpp
return x >= T(0) ? x : -x; return x >= T(0) ? x : -x;
} }
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
constexpr sqr(T x) noexcept {
return x * x;
}
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, T>
constexpr sign(T x) noexcept { constexpr sign(T x) noexcept {
@@ -158,6 +164,12 @@ namespace vmath_hpp
return x * (T(1) - a) + y * a; return x * (T(1) - a) + y * a;
} }
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr lerp(T x, T y, T x_a, T y_a) noexcept {
return x * x_a + y * y_a;
}
template < typename T > template < typename T >
[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T> [[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, T>
constexpr step(T edge, T x) noexcept { constexpr step(T edge, T x) noexcept {

View File

@@ -55,6 +55,24 @@ namespace vmath_hpp::detail::impl
return { f(a[Is], b[Is], c[Is])... }; return { f(a[Is], b[Is], c[Is])... };
} }
template < typename A, typename B, typename C, typename D, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join_impl(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
const vec<C, Size>& c,
const vec<D, Size>& d,
std::index_sequence<Is...>
) -> vec<decltype(f(
std::declval<A>(),
std::declval<B>(),
std::declval<C>(),
std::declval<D>())), Size>
{
return { f(a[Is], b[Is], c[Is], d[Is])... };
}
template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join_impl( auto fold_join_impl(
@@ -125,6 +143,19 @@ namespace vmath_hpp::detail
std::forward<F>(f), a, b, c, std::make_index_sequence<Size>{}); std::forward<F>(f), a, b, c, std::make_index_sequence<Size>{});
} }
template < typename A, typename B, typename C, typename D, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto map_join(
F&& f,
const vec<A, Size>& a,
const vec<B, Size>& b,
const vec<C, Size>& c,
const vec<D, Size>& d
) {
return impl::map_join_impl(
std::forward<F>(f), a, b, c, d, std::make_index_sequence<Size>{});
}
template < typename A, typename B, std::size_t Size, typename F > template < typename A, typename B, std::size_t Size, typename F >
[[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE
auto fold_join( auto fold_join(
@@ -715,10 +746,29 @@ namespace vmath_hpp
} }
template < typename T, std::size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> lerp(const vec<T, Size>& xs, const vec<T, Size>& ys, const vec<T, Size>& as) { [[nodiscard]] constexpr vec<T, Size> lerp(const vec<T, Size>& xs, const vec<T, Size>& ys, T x_a, T y_a) {
return map_join([x_a, y_a](T x, T y) { return lerp(x, y, x_a, y_a); }, xs, ys);
}
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> lerp(
const vec<T, Size>& xs,
const vec<T, Size>& ys,
const vec<T, Size>& as)
{
return map_join([](T x, T y, T a) { return lerp(x, y, a); }, xs, ys, as); return map_join([](T x, T y, T a) { return lerp(x, y, a); }, xs, ys, as);
} }
template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> lerp(
const vec<T, Size>& xs,
const vec<T, Size>& ys,
const vec<T, Size>& xs_a,
const vec<T, Size>& ys_a)
{
return map_join([](T x, T y, T x_a, T y_a) { return lerp(x, y, x_a, y_a); }, xs, ys, xs_a, ys_a);
}
template < typename T, std::size_t Size > template < typename T, std::size_t Size >
[[nodiscard]] constexpr vec<T, Size> step(T edge, const vec<T, Size>& xs) { [[nodiscard]] constexpr vec<T, Size> step(T edge, const vec<T, Size>& xs) {
return map_join([edge](T x) { return step(edge, x); }, xs); return map_join([edge](T x) { return step(edge, x); }, xs);

View File

@@ -55,6 +55,9 @@ TEST_CASE("vmath/fun") {
STATIC_REQUIRE(vmath_hpp::abs(1.f) == uapprox(1.f)); STATIC_REQUIRE(vmath_hpp::abs(1.f) == uapprox(1.f));
STATIC_REQUIRE(vmath_hpp::abs(-1.f) == uapprox(1.f)); STATIC_REQUIRE(vmath_hpp::abs(-1.f) == uapprox(1.f));
STATIC_REQUIRE(sqr(2) == 4);
STATIC_REQUIRE(sqr(-4.f) == uapprox(16.f));
STATIC_REQUIRE(sign(2) == 1); STATIC_REQUIRE(sign(2) == 1);
STATIC_REQUIRE(sign(-2) == -1); STATIC_REQUIRE(sign(-2) == -1);
STATIC_REQUIRE(sign(0) == 0); STATIC_REQUIRE(sign(0) == 0);
@@ -121,6 +124,10 @@ TEST_CASE("vmath/fun") {
STATIC_REQUIRE(lerp(2.f, 10.f, 0.5f) == uapprox(6.f)); STATIC_REQUIRE(lerp(2.f, 10.f, 0.5f) == uapprox(6.f));
STATIC_REQUIRE(lerp(2.f, 10.f, 1.f) == uapprox(10.f)); STATIC_REQUIRE(lerp(2.f, 10.f, 1.f) == uapprox(10.f));
STATIC_REQUIRE(lerp(2.f, 10.f, 0.f, 1.f) == uapprox(10.f));
STATIC_REQUIRE(lerp(2.f, 10.f, 1.f, 0.f) == uapprox(2.f));
STATIC_REQUIRE(lerp(2.f, 10.f, 0.5f, 0.2f) == uapprox(3.f));
STATIC_REQUIRE(step(0.5f, 0.4f) == uapprox(0.f)); STATIC_REQUIRE(step(0.5f, 0.4f) == uapprox(0.f));
STATIC_REQUIRE(step(0.5f, 0.6f) == uapprox(1.f)); STATIC_REQUIRE(step(0.5f, 0.6f) == uapprox(1.f));
STATIC_REQUIRE(smoothstep(0.f, 1.f, 0.1f) == uapprox(0.028f)); STATIC_REQUIRE(smoothstep(0.f, 1.f, 0.1f) == uapprox(0.028f));

View File

@@ -206,10 +206,18 @@ TEST_CASE("vmath/vec_fun") {
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.5f) == uapprox2(6.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.5f) == uapprox2(6.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 1.f) == uapprox2(10.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 1.f) == uapprox2(10.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.f, 1.f) == uapprox2(10.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 1.f, 0.f) == uapprox2(2.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), 0.5f, 0.2f) == uapprox2(3.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.f)) == uapprox2(2.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.f)) == uapprox2(2.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.5f)) == uapprox2(6.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.5f)) == uapprox2(6.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(1.f)) == uapprox2(10.f)); STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(1.f)) == uapprox2(10.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.f), float2(1.f)) == uapprox2(10.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(1.f), float2(0.f)) == uapprox2(2.f));
STATIC_REQUIRE(lerp(float2(2.f), float2(10.f), float2(0.5f), float2(0.2f)) == uapprox2(3.f));
STATIC_REQUIRE(step(0.5f, float2(0.4f)) == uapprox2(0.f)); STATIC_REQUIRE(step(0.5f, float2(0.4f)) == uapprox2(0.f));
STATIC_REQUIRE(step(0.5f, float2(0.6f)) == uapprox2(1.f)); STATIC_REQUIRE(step(0.5f, float2(0.6f)) == uapprox2(1.f));
STATIC_REQUIRE(step(float2(0.5f), float2(0.4f)) == uapprox2(0.f)); STATIC_REQUIRE(step(float2(0.5f), float2(0.4f)) == uapprox2(0.f));