mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add curve/bezier, curve/catmull_rom_sprine
This commit is contained in:
parent
3029507c05
commit
b55e74de78
5 changed files with 325 additions and 0 deletions
16
sprout/math/curve.hpp
Normal file
16
sprout/math/curve.hpp
Normal file
|
@ -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 <sprout/config.hpp>
|
||||
#include <sprout/math/curve/curve_point.hpp>
|
||||
#include <sprout/math/curve/bezier.hpp>
|
||||
#include <sprout/math/curve/catmull_rom_sprine.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_CURVE_HPP
|
144
sprout/math/curve/bezier.hpp
Normal file
144
sprout/math/curve/bezier.hpp
Normal file
|
@ -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 <sprout/config.hpp>
|
||||
#include <sprout/workaround/std/cstddef.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/tuple/tuple/get.hpp>
|
||||
#include <sprout/tuple/tuple/make_tuple.hpp>
|
||||
#include <sprout/math/curve/curve_point.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename Points, typename T, std::size_t N = sprout::tuple_size<Points>::value - 1>
|
||||
class bezier_impl;
|
||||
template<typename Points, typename T>
|
||||
class bezier_impl<Points, T, 2> {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
call(Points const& p, T const& t) {
|
||||
using sprout::tuples::nested_get;
|
||||
using sprout::detail::pow2;
|
||||
return sprout::math::curve_point_traits<Points>::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<typename Points, typename T>
|
||||
class bezier_impl<Points, T, 3> {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::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<Points>::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<typename Points, typename T>
|
||||
class bezier_impl<Points, T, 4> {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::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<Points>::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<typename Points, typename T>
|
||||
class bezier_impl<Points, T, 5> {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::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<Points>::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<typename Points, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
bezier(T const& t, Points const& p) {
|
||||
return sprout::math::detail::bezier_impl<Points, T>::call(p, t);
|
||||
}
|
||||
template<std::size_t N, typename Points, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
bezier(T const& t, Points const& p) {
|
||||
return sprout::math::detail::bezier_impl<Points, T, N>::call(p, t);
|
||||
}
|
||||
|
||||
template<typename P0, typename P1, typename P2, typename... PTail, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<sprout::tuples::tuple<P0 const&, P1 const&, P2 const&, PTail const&...> >::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<std::size_t N, typename P0, typename P1, typename P2, typename... PTail, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<sprout::tuples::tuple<P0 const&, P1 const&, P2 const&, PTail const&...> >::type
|
||||
bezier(T const& t, P0 const& p0, P1 const& p1, P2 const& p2, PTail const&... p) {
|
||||
return sprout::math::bezier<N>(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
|
122
sprout/math/curve/catmull_rom_sprine.hpp
Normal file
122
sprout/math/curve/catmull_rom_sprine.hpp
Normal file
|
@ -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 <sprout/config.hpp>
|
||||
#include <sprout/detail/pow.hpp>
|
||||
#include <sprout/tuple/tuple/get.hpp>
|
||||
#include <sprout/tuple/tuple/make_tuple.hpp>
|
||||
#include <sprout/math/curve/curve_point.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
namespace detail {
|
||||
template<typename Points, typename T>
|
||||
class catmull_rom_sprine_impl {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::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<Points>::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<typename Points, typename T>
|
||||
class catmull_rom_sprine_start_impl {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
call(Points const& p, T const& t) {
|
||||
using sprout::tuples::nested_get;
|
||||
using sprout::detail::pow2;
|
||||
return sprout::math::curve_point_traits<Points>::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<typename Points, typename T>
|
||||
class catmull_rom_sprine_end_impl {
|
||||
public:
|
||||
static SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
call(Points const& p, T const& t) {
|
||||
using sprout::tuples::nested_get;
|
||||
using sprout::detail::pow2;
|
||||
return sprout::math::curve_point_traits<Points>::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<typename Points, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
catmull_rom_sprine(T const& t, Points const& p) {
|
||||
return sprout::math::detail::catmull_rom_sprine_impl<Points, T>::call(p, t);
|
||||
}
|
||||
template<typename Points, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
catmull_rom_sprine_start(T const& t, Points const& p) {
|
||||
return sprout::math::detail::catmull_rom_sprine_start_impl<Points, T>::call(p, t);
|
||||
}
|
||||
template<typename Points, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<Points>::type
|
||||
catmull_rom_sprine_end(T const& t, Points const& p) {
|
||||
return sprout::math::detail::catmull_rom_sprine_end_impl<Points, T>::call(p, t);
|
||||
}
|
||||
|
||||
template<typename P0, typename P1, typename P2, typename P3, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<sprout::tuples::tuple<P0 const&, P1 const&, P2 const&, P3 const&> >::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<typename P0, typename P1, typename P2, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<sprout::tuples::tuple<P0 const&, P1 const&, P2 const&> >::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<typename P0, typename P1, typename P2, typename T>
|
||||
inline SPROUT_CONSTEXPR typename sprout::math::curve_point_result<sprout::tuples::tuple<P0 const&, P1 const&, P2 const&> >::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
|
42
sprout/math/curve/curve_point.hpp
Normal file
42
sprout/math/curve/curve_point.hpp
Normal file
|
@ -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 <utility>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/tuple/traits.hpp>
|
||||
#include <sprout/type_traits/identity.hpp>
|
||||
#include <sprout/type_traits/remove_cvref.hpp>
|
||||
#include <sprout/tuple/traits.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace math {
|
||||
//
|
||||
// curve_point
|
||||
// curve_point_traits
|
||||
// curve_point_result
|
||||
//
|
||||
template<typename Points>
|
||||
struct curve_point
|
||||
: public sprout::remove_cvref<decltype(sprout::tuples::nested_get<0>(std::declval<Points const&>()))>
|
||||
{};
|
||||
template<typename Points>
|
||||
struct curve_point_traits
|
||||
: public sprout::tuples::tuple_construct_traits<typename sprout::math::curve_point<Points>::type>
|
||||
{};
|
||||
template<typename Points>
|
||||
struct curve_point_result
|
||||
: public sprout::identity<
|
||||
typename sprout::math::curve_point_traits<Points>::copied_type
|
||||
>
|
||||
{};
|
||||
} // namespace math
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_MATH_CURVE_CURVE_POINT_HPP
|
|
@ -48,6 +48,7 @@
|
|||
#include <sprout/limits.hpp>
|
||||
#include <sprout/logic.hpp>
|
||||
#include <sprout/math.hpp>
|
||||
#include <sprout/math/curve.hpp>
|
||||
#include <sprout/memory.hpp>
|
||||
#include <sprout/net.hpp>
|
||||
#include <sprout/none.hpp>
|
||||
|
|
Loading…
Reference in a new issue