Go to the documentation of this file. 1 #ifndef EAGINE_MATH_CURVE_HPP
9 #define EAGINE_MATH_CURVE_HPP
11 #include "../assert.hpp"
12 #include "../integer_range.hpp"
13 #include "../memory/span_algo.hpp"
14 #include "../span.hpp"
15 #include "../types.hpp"
16 #include "../valid_if/positive.hpp"
34 template <
typename Type,
typename Parameter, span_
size_t Order>
40 return ((points.size() - 1) != Order) &&
41 ((points.size() - 1) % Order) == 0;
49 static auto are_separated(
const std::vector<Type>& points) noexcept
51 return (points.size() % (Order + 1)) == 0;
62 return !points.empty() &&
74 : _points{std::move(points)}
87 : _points{std::move(points)}
88 , _connected{connected} {
100 template <
typename P,
typename S>
102 : _points(points.begin(), points.end())
115 template <
typename P,
typename S>
117 : _points(points.begin(), points.end())
118 , _connected(connected) {
123 auto segment_step() const noexcept ->
span_size_t {
125 return _connected ? Order : Order + 1;
132 return _connected ?
span_size(_points.size() - 1) / Order
133 :
span_size(_points.size()) / (Order + 1);
142 static auto wrap(Parameter t) noexcept -> Parameter {
143 const Parameter
zero{0};
144 const Parameter one{1};
146 t += std::floor(std::fabs(t)) + one;
150 EAGINE_ASSERT(t >=
zero && t <= one);
156 const Parameter
zero{0};
157 const Parameter one{1};
162 EAGINE_ASSERT(t >=
zero && t < one);
165 const auto t_sub = toffs - std::floor(toffs);
166 const auto poffs =
span_size_t(toffs) * segment_step();
167 EAGINE_ASSERT(poffs <
span_size(_points.size()) - Order);
169 return _bezier(t_sub,
skip(
view(_points), poffs));
173 auto position(Parameter t)
const noexcept -> Type {
180 const auto sstep = segment_step();
185 auto p = dest.begin();
186 const Parameter t_step = Parameter(1) /
extract(n);
189 const auto poffs = i * sstep;
190 auto t_sub = Parameter(0);
192 EAGINE_MAYBE_UNUSED(j);
193 EAGINE_ASSERT(p != dest.end());
194 *p = Type(_bezier(t_sub,
skip(
view(_points), poffs)));
200 EAGINE_ASSERT(p != dest.end());
203 EAGINE_ASSERT(p == dest.end());
208 -> std::vector<Type> {
209 std::vector<Type> result;
217 const auto sstep = segment_step();
220 std::vector<Type> new_points(
std_size(s * Order));
221 auto p = new_points.begin();
225 const auto k = i * sstep + j;
226 EAGINE_ASSERT(p != new_points.end());
231 EAGINE_ASSERT(p == new_points.end());
233 return {std::move(new_points),
false};
237 static_assert(Order > 0);
239 std::vector<Type> _points;
251 template <
typename Type,
typename Parameter>
255 template <
typename P,
typename S>
258 Parameter r = Parameter(1) / Parameter(3))
259 :
bezier_curves<Type, Parameter, 3>(_make_cpoints(points, r)) {}
262 template <
typename P,
typename S>
265 -> std::vector<Type> {
267 EAGINE_ASSERT(n != 0);
269 std::vector<Type> result(
std_size(n * 3 + 1));
270 auto ir = result.begin();
273 const auto a = (n + i - 1) % n;
275 const auto c = (i + 1) % n;
276 const auto d = (i + 2) % n;
278 EAGINE_ASSERT(ir != result.end());
281 EAGINE_ASSERT(ir != result.end());
282 *ir = Type(points[b] + (points[c] - points[a]) * r);
284 EAGINE_ASSERT(ir != result.end());
285 *ir = Type(points[c] + (points[b] - points[d]) * r);
289 EAGINE_ASSERT(ir != result.end());
292 EAGINE_ASSERT(ir == result.end());
300 #endif // EAGINE_MATH_CURVE_HPP
auto control_points() const noexcept -> const std::vector< Type > &
Returns the contol points of the curve.
Definition: curve.hpp:137
auto position01(Parameter t) const noexcept -> Type
Gets the point on the curve at position t (must be in (0.0, 1.0)).
Definition: curve.hpp:155
bezier_curves(std::vector< Type > points)
Creates the bezier curves from the control points.
Definition: curve.hpp:73
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
static constexpr auto span_size(T v) noexcept
Converts argument to span size type.
Definition: types.hpp:59
static constexpr auto extract(api_result_value< Result, api_result_validity::never > &) noexcept -> Result &
Overload of extract for api_result_value.
Definition: c_api_wrap.hpp:270
Primary template for conditionally valid values.
Definition: decl.hpp:49
static constexpr auto view(T *addr, S size) noexcept -> const_span< T >
Creates a view starting at the specified pointer and specified length.
Definition: span.hpp:458
A sequence of Bezier curves, possibly connected at end points.
Definition: curve.hpp:35
cubic_bezier_loop(memory::basic_span< const Type, P, S > points, Parameter r=Parameter(1)/Parameter(3))
Creates a loop passing through the sequence of the input points.
Definition: curve.hpp:256
Basic N-dimensional vector implementation template.
Definition: fwd.hpp:19
auto is_connected() const noexcept -> bool
Returns true if the individual curves are connected.
Definition: curve.hpp:45
bezier_curves(memory::basic_span< const Type, P, S > points, bool connected)
Creates the bezier curves from the control points.
Definition: curve.hpp:116
static constexpr auto std_size(T v) noexcept
Converts argument to std size type.
Definition: types.hpp:52
Non-owning view of a contiguous range of memory with ValueType elements.
Definition: flatten_fwd.hpp:16
auto segment_count() const noexcept -> span_size_t
Returns the count of individual curves in the sequence.
Definition: curve.hpp:129
static constexpr auto skip(basic_span< T, P, S > s, L l) noexcept -> basic_span< T, P, S >
Skips a specified count of elements from the front of a span.
Definition: span_algo.hpp:60
Math-related code is placed in this namespace.
Definition: eagine.hpp:48
static auto wrap(Parameter t) noexcept -> Parameter
Wraps the parameter value to [0.0, 1.0].
Definition: curve.hpp:142
static auto zero(basic_span< T, P, S > spn) -> std::enable_if_t< std::is_integral_v< T >||std::is_floating_point_v< T >, basic_span< T, P, S >>
Fills a span with zero value of type T.
Definition: span_algo.hpp:548
static auto are_connected(const std::vector< Type > &points) noexcept -> bool
Returns whether the curves made from points are connected.
Definition: curve.hpp:38
A closed smooth cubic Bezier spline passing through all input points.
Definition: curve.hpp:252
bezier_curves(memory::basic_span< const Type, P, S > points)
Creates the bezier curves from the control points.
Definition: curve.hpp:101
static auto points_are_ok(const std::vector< Type > &points) noexcept -> bool
checks if the sequence of control points is OK for this curve type.
Definition: curve.hpp:60
auto position(Parameter t) const noexcept -> Type
Gets the point on the curve at position t wrapped to [0.0, 1.0].
Definition: curve.hpp:173
integer_range(B, E) -> integer_range< std::common_type_t< B, E >>
Deduction guide for integer_range.
auto derivative() const noexcept -> bezier_curves< Type, Parameter, Order - 1 >
Returns a derivative of this curve.
Definition: curve.hpp:215
auto approximate(valid_if_positive< span_size_t > n) const -> std::vector< Type >
Returns a sequence of points on the curve (n points per segment).
Definition: curve.hpp:207
bezier_curves(std::vector< Type > points, bool connected)
Creates the bezier curves from the control points.
Definition: curve.hpp:86
auto is_separated() const noexcept -> bool
Returns true if the individual curves are disconnected.
Definition: curve.hpp:55
void approximate(std::vector< Type > &dest, valid_if_positive< span_size_t > n) const noexcept
Makes a sequence of points on the curve (n points per segment).
Definition: curve.hpp:178