From b55e74de78d2df7f242b6ae4efe6fcb7835eca4b Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Sat, 10 Jan 2015 19:30:09 +0900 Subject: [PATCH] add curve/bezier, curve/catmull_rom_sprine --- sprout/math/curve.hpp | 16 +++ sprout/math/curve/bezier.hpp | 144 +++++++++++++++++++++++ sprout/math/curve/catmull_rom_sprine.hpp | 122 +++++++++++++++++++ sprout/math/curve/curve_point.hpp | 42 +++++++ testspr/header_all.hpp | 1 + 5 files changed, 325 insertions(+) create mode 100644 sprout/math/curve.hpp create mode 100644 sprout/math/curve/bezier.hpp create mode 100644 sprout/math/curve/catmull_rom_sprine.hpp create mode 100644 sprout/math/curve/curve_point.hpp diff --git a/sprout/math/curve.hpp b/sprout/math/curve.hpp new file mode 100644 index 00000000..e3da3d66 --- /dev/null +++ b/sprout/math/curve.hpp @@ -0,0 +1,16 @@ +/*============================================================================= + Copyright (c) 2011-2014 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_HPP +#define SPROUT_MATH_CURVE_HPP + +#include +#include +#include +#include + +#endif // #ifndef SPROUT_MATH_CURVE_HPP diff --git a/sprout/math/curve/bezier.hpp b/sprout/math/curve/bezier.hpp new file mode 100644 index 00000000..87dafe1d --- /dev/null +++ b/sprout/math/curve/bezier.hpp @@ -0,0 +1,144 @@ +/*============================================================================= + Copyright (c) 2011-2015 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(sprout::tuples::forward_as_tuple(p0, p1, p2, 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(sprout::tuples::forward_as_tuple(p0, p1, p2, p...), t); + } + } // namespace math + + using sprout::math::bezier; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_CURVE_BEZIER_HPP diff --git a/sprout/math/curve/catmull_rom_sprine.hpp b/sprout/math/curve/catmull_rom_sprine.hpp new file mode 100644 index 00000000..1b9faf29 --- /dev/null +++ b/sprout/math/curve/catmull_rom_sprine.hpp @@ -0,0 +1,122 @@ +/*============================================================================= + Copyright (c) 2011-2015 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_CATMULL_ROM_SPRINE_HPP +#define SPROUT_MATH_CURVE_CATMULL_ROM_SPRINE_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + namespace detail { + template + class catmull_rom_sprine_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( + (-nested_get<0, 0>(p) + 3 * nested_get<1, 0>(p) - 3 * nested_get<2, 0>(p) + nested_get<3, 0>(p)) / 2 * pow3(t) + + (2 * nested_get<0, 0>(p) - 5 * nested_get<1, 0>(p) + 4 * nested_get<2, 0>(p) - nested_get<3, 0>(p)) / 2 * pow2(t) + + (-nested_get<0, 0>(p) + nested_get<2, 0>(p)) / 2 * t + + nested_get<1, 0>(p) + , + (-nested_get<0, 1>(p) + 3 * nested_get<1, 1>(p) - 3 * nested_get<2, 1>(p) + nested_get<3, 1>(p)) / 2 * pow3(t) + + (2 * nested_get<0, 1>(p) - 5 * nested_get<1, 1>(p) + 4 * nested_get<2, 1>(p) - nested_get<3, 1>(p)) / 2 * pow2(t) + + (-nested_get<0, 1>(p) + nested_get<2, 1>(p)) / 2 * t + + nested_get<1, 1>(p) + ); + } + }; + template + class catmull_rom_sprine_start_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( + (nested_get<0, 0>(p) - 2 * nested_get<1, 0>(p) + nested_get<2, 0>(p)) / 2 * pow2(t) + + (-3 * nested_get<0, 0>(p) + 4 * nested_get<1, 0>(p) - nested_get<2, 0>(p)) / 2 * t + + nested_get<0, 0>(p) + , + (nested_get<0, 1>(p) - 2 * nested_get<1, 1>(p) + nested_get<2, 1>(p)) / 2 * pow2(t) + + (-3 * nested_get<0, 1>(p) + 4 * nested_get<1, 1>(p) - nested_get<2, 1>(p)) / 2 * t + + nested_get<0, 1>(p) + ); + } + }; + template + class catmull_rom_sprine_end_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( + (nested_get<0, 0>(p) - 2 * nested_get<1, 0>(p) + nested_get<2, 0>(p)) / 2 * pow2(t) + + (-nested_get<0, 0>(p) + nested_get<2, 0>(p)) / 2 * t + + nested_get<1, 0>(p) + , + (nested_get<0, 1>(p) - 2 * nested_get<1, 1>(p) + nested_get<2, 1>(p)) / 2 * pow2(t) + + (-nested_get<0, 1>(p) + nested_get<2, 1>(p)) / 2 * t + + nested_get<1, 1>(p) + ); + } + }; + } // namespace detail + + // + // catmull_rom_sprine + // catmull_rom_sprine_start + // catmull_rom_sprine_end + // + template + inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type + catmull_rom_sprine(T const& t, Points const& p) { + return sprout::math::detail::catmull_rom_sprine_impl::call(p, t); + } + template + inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type + catmull_rom_sprine_start(T const& t, Points const& p) { + return sprout::math::detail::catmull_rom_sprine_start_impl::call(p, t); + } + template + inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result::type + catmull_rom_sprine_end(T const& t, Points const& p) { + return sprout::math::detail::catmull_rom_sprine_end_impl::call(p, t); + } + + template + inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result >::type + catmull_rom_sprine(T const& t, P0 const& p0, P1 const& p1, P2 const& p2, P3 const& p3) { + return sprout::math::catmull_rom_sprine(sprout::tuples::forward_as_tuple(p0, p1, p2, p3), t); + } + template + inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result >::type + catmull_rom_sprine_start(T const& t, P0 const& p0, P1 const& p1, P2 const& p2) { + return sprout::math::catmull_rom_sprine_start(sprout::tuples::forward_as_tuple(p0, p1, p2), t); + } + template + inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result >::type + catmull_rom_sprine_end(T const& t, P0 const& p0, P1 const& p1, P2 const& p2) { + return sprout::math::catmull_rom_sprine_end(sprout::tuples::forward_as_tuple(p0, p1, p2), t); + } + } // namespace math + + using sprout::math::catmull_rom_sprine; + using sprout::math::catmull_rom_sprine_start; + using sprout::math::catmull_rom_sprine_end; +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_CURVE_CATMULL_ROM_SPRINE_HPP diff --git a/sprout/math/curve/curve_point.hpp b/sprout/math/curve/curve_point.hpp new file mode 100644 index 00000000..53a65b01 --- /dev/null +++ b/sprout/math/curve/curve_point.hpp @@ -0,0 +1,42 @@ +/*============================================================================= + Copyright (c) 2011-2015 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_CURVE_POINT_HPP +#define SPROUT_MATH_CURVE_CURVE_POINT_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace math { + // + // curve_point + // curve_point_traits + // curve_point_result + // + template + struct curve_point + : public sprout::remove_cvref(std::declval()))> + {}; + template + struct curve_point_traits + : public sprout::tuples::tuple_construct_traits::type> + {}; + template + struct curve_point_result + : public sprout::identity< + typename sprout::math::curve_point_traits::copied_type + > + {}; + } // namespace math +} // namespace sprout + +#endif // #ifndef SPROUT_MATH_CURVE_CURVE_POINT_HPP diff --git a/testspr/header_all.hpp b/testspr/header_all.hpp index 3a0f78e7..8a00b533 100644 --- a/testspr/header_all.hpp +++ b/testspr/header_all.hpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include