/*============================================================================= Copyright (c) 2011-2017 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_MATH_CURVE_BEZIER_HPP #define SPROUT_MATH_CURVE_BEZIER_HPP #include #include #include #include #include #include namespace sprout { namespace math { namespace detail { template::value - 1> class bezier_impl; template class bezier_impl { public: static SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type call(Points const& p, T const& t) { using sprout::tuples::nested_get; using sprout::detail::pow2; return sprout::math::curve_point_traits::make( pow2(1 - t) * nested_get<0, 0>(p) + 2 * t * (1 - t) * nested_get<1, 0>(p) + pow2(t) * nested_get<2, 0>(p) , pow2(1 - t) * nested_get<0, 1>(p) + 2 * t * (1 - t) * nested_get<1, 1>(p) + pow2(t) * nested_get<2, 1>(p) ); } }; template class bezier_impl { public: static SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type call(Points const& p, T const& t) { using sprout::tuples::nested_get; using sprout::detail::pow2; using sprout::detail::pow3; return sprout::math::curve_point_traits::make( pow3(1 - t) * nested_get<0, 0>(p) + 3 * t * pow2(1 - t) * nested_get<1, 0>(p) + 3 * pow2(t) * (1 - t) * nested_get<2, 0>(p) + pow3(t) * nested_get<3, 0>(p) , pow3(1 - t) * nested_get<0, 1>(p) + 3 * t * pow2(1 - t) * nested_get<1, 1>(p) + 3 * pow2(t) * (1 - t) * nested_get<2, 1>(p) + pow3(t) * nested_get<3, 1>(p) ); } }; template class bezier_impl { public: static SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type call(Points const& p, T const& t) { using sprout::tuples::nested_get; using sprout::detail::pow2; using sprout::detail::pow3; using sprout::detail::pow4; return sprout::math::curve_point_traits::make( pow4(1 - t) * nested_get<0, 0>(p) + 4 * t * pow3(1 - t) * nested_get<1, 0>(p) + 6 * pow2(t) * pow2(1 - t) * nested_get<2, 0>(p) + 4 * pow3(t) * (1 - t) * nested_get<3, 0>(p) + pow4(t) * nested_get<4, 0>(p) , pow4(1 - t) * nested_get<0, 1>(p) + 4 * t * pow3(1 - t) * nested_get<1, 1>(p) + 6 * pow2(t) * pow2(1 - t) * nested_get<2, 1>(p) + 4 * pow3(t) * (1 - t) * nested_get<3, 1>(p) + pow4(t) * nested_get<4, 1>(p) ); } }; template class bezier_impl { public: static SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type call(Points const& p, T const& t) { using sprout::tuples::nested_get; using sprout::detail::pow2; using sprout::detail::pow3; using sprout::detail::pow4; using sprout::detail::pow5; return sprout::math::curve_point_traits::make( pow5(1 - t) * nested_get<0, 0>(p) + 5 * t * pow4(1 - t) * nested_get<1, 0>(p) + 10 * pow2(t) * pow3(1 - t) * nested_get<2, 0>(p) + 10 * pow3(t) * pow2(1 - t) * nested_get<3, 0>(p) + 5 * pow4(t) * (1 - t) * nested_get<4, 0>(p) + pow5(t) * nested_get<5, 0>(p) , pow5(1 - t) * nested_get<0, 1>(p) + 5 * t * pow4(1 - t) * nested_get<1, 1>(p) + 10 * pow2(t) * pow3(1 - t) * nested_get<2, 1>(p) + 10 * pow3(t) * pow2(1 - t) * nested_get<3, 1>(p) + 5 * pow4(t) * (1 - t) * nested_get<4, 1>(p) + pow5(t) * nested_get<5, 1>(p) ); } }; } // namespace detail // // bezier // template inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type bezier(T const& t, Points const& p) { return sprout::math::detail::bezier_impl::call(p, t); } template inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type bezier(T const& t, Points const& p) { return sprout::math::detail::bezier_impl::call(p, t); } template inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result >::type bezier(T const& t, P0 const& p0, P1 const& p1, P2 const& p2, PTail const&... p) { return sprout::math::bezier(t, sprout::tuples::forward_as_tuple(p0, p1, p2, p...)); } template inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result >::type bezier(T const& t, P0 const& p0, P1 const& p1, P2 const& p2, PTail const&... p) { return sprout::math::bezier(t, sprout::tuples::forward_as_tuple(p0, p1, p2, p...)); } } // namespace math using sprout::math::bezier; } // namespace sprout #endif // #ifndef SPROUT_MATH_CURVE_BEZIER_HPP