.. _program_listing_file_include_ripple_math_lerp.hpp: Program Listing for File lerp.hpp ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``include/ripple/math/lerp.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #ifndef RIPPLE_MATH_LERP_HPP #define RIPPLE_MATH_LERP_HPP #include "math.hpp" #include #include #include namespace ripple::math { /*==--- [1d lerp] ----------------------------------------------------------==*/ template < typename Iterator, typename Weights, array_size_enable_t = 0> ripple_all auto lerp(Iterator&& it, const Weights& weights) noexcept -> typename iterator_traits_t::CopyType { static_assert( is_iterator_v, "Linear interpolation requires an iterator."); using value_t = std::decay_t; // Comptute values used for the interpolation: const auto sign = math::sign(weights[dimx()]); const auto abs_w = std::abs(weights[dimx()]); const auto abs_off = std::floor(abs_w); const auto off = sign * abs_off; const auto factor = abs_w - abs_off; return (*it.offset(dimx(), off)) * (value_t(1) - factor) + (*it.offset(dimx(), off + sign)) * factor; } /*==--- [2d lerp] ----------------------------------------------------------==*/ template < typename Iterator, typename Weights, array_size_enable_t = 0> ripple_all auto lerp(const Iterator& it, const Weights& weights) noexcept -> typename iterator_traits_t::CopyType { static_assert( is_array_v, "Linear interpolation requires a weight array."); static_assert( array_traits_t::size, "Iterator dimensionality must match size of weight array."); using T = std::decay_t; // Compute offset params: const T absx = std::abs(weights[dimx()]); const T fl_absx = std::floor(absx); const int sign_x = math::sign(weights[dimx()]); const int offx = sign_x * fl_absx; const T absy = std::abs(weights[dimy()]); const T fl_absy = std::floor(absy); const int sign_y = math::sign(weights[dimy()]); const int offy = sign_y * fl_absy; // Compute the factors: const T wx = absx - fl_absx; const T wy = absy - fl_absy; const T fx = T{1} - wx; const T fy = T{1} - wy; // clang-format off auto a = it.offset(dimx(), offx).offset(dimy(), offy); return (*a) * (fx * fy) + (*a.offset(dimx(), sign_x)) * (wx * fy) + (*a.offset(dimy(), sign_y)) * (wy * fx) + (*a.offset(dimx(), sign_x) .offset(dimy(), sign_y)) * (wx * wy); // clang-format on } /*==--- [3d lerp] ----------------------------------------------------------==*/ template < typename Iterator, typename Weights, array_size_enable_t = 0> ripple_all auto lerp(Iterator&& it, const Weights& weights) -> typename iterator_traits_t::CopyType { static_assert( is_array_v, "Linear interpolation requires a weight array."); static_assert( array_traits_t::size == 3, "Iterator dimensionality must match size of weight array."); using T = std::decay_t; // Compute offset params: const T absx = std::abs(weights[dimx()]); const T fl_absx = std::floor(absx); const int sign_x = math::sign(weights[dimx()]); const int offx = sign_x * fl_absx; const T absy = std::abs(weights[dimy()]); const T fl_absy = std::floor(absy); const int sign_y = math::sign(weights[dimy()]); const int offy = sign_y * fl_absy; const T absz = std::abs(weights[dimz()]); const T fl_absz = std::floor(absz); const int sign_z = math::sign(weights[dimz()]); const int offz = sign_z * fl_absz; // Compute the factors: const T wx = absx - fl_absx; const T wy = absy - fl_absy; const T wz = absz - fl_absz; const T fx = T{1} - wx; const T fy = T{1} - wy; const T fz = T{1} - wz; // Offset to the close (c) and far (f) cell in z plane: auto c = it.offset(dimx(), offx).offset(dimy(), offy).offset(dimz(), offz); auto f = c.offset(dimz(), sign_z); // clang-format off return (*c) * (fx * fy * fz) + (*c.offset(dimx(), sign_x)) * (wx * fy * fz) + (*c.offset(dimy(), sign_y)) * (wy * fx * fz) + (*c.offset(dimx(), sign_x).offset(dimy(), sign_y)) * (wx * wy * fz) + (*f) * (fx * fy * wz) + (*f.offset(dimx(), sign_x)) * (wx * fy * wz) + (*f.offset(dimy(), sign_y)) * (wy * fx * wz) + (*f.offset(dimx(), sign_x).offset(dimy(), sign_y)) * (wx * wy * wz); // clang-format on } } // namespace ripple::math #endif // RIPPLE_MATH_LERP_HPP