10 #ifndef EIGEN_SPLINE_H 11 #define EIGEN_SPLINE_H 14 #include "./InternalHeaderCheck.h" 16 #include "SplineFwd.h" 36 template <
typename Scalar_,
int Dim_,
int Degree_>
44 typedef typename SplineTraits<Spline>::PointType
PointType;
80 template <
typename OtherVectorType,
typename OtherArrayType>
87 template <
int OtherDegree>
125 typename SplineTraits<Spline>::DerivativeType
derivatives(
Scalar u, DenseIndex order)
const;
132 template <
int DerivativeOrder>
133 typename SplineTraits<Spline, DerivativeOrder>::DerivativeType
derivatives(
Scalar u,
134 DenseIndex order = DerivativeOrder)
const;
174 template <
int DerivativeOrder>
176 Scalar u, DenseIndex order = DerivativeOrder)
const;
181 DenseIndex
degree()
const;
192 static DenseIndex
Span(
typename SplineTraits<Spline>::Scalar u, DenseIndex
degree,
193 const typename SplineTraits<Spline>::KnotVectorType&
knots);
221 template <
typename DerivativeType>
223 const DenseIndex order,
const DenseIndex p,
228 template <
typename Scalar_,
int Dim_,
int Degree_>
233 if (u <= knots(0))
return degree;
234 const Scalar* pos = std::upper_bound(knots.data() + degree - 1, knots.data() + knots.size() - degree - 1, u);
235 return static_cast<DenseIndex
>(std::distance(knots.data(), pos) - 1);
238 template <
typename Scalar_,
int Dim_,
int Degree_>
242 const DenseIndex p = degree;
258 for (DenseIndex j = 1; j <= p; ++j) {
260 for (DenseIndex r = 0; r < j; r++) {
261 const Scalar tmp = N(r) / (right(r + 1) + left(j - r));
262 N[r] = saved + right(r + 1) * tmp;
263 saved = left(j - r) * tmp;
270 template <
typename Scalar_,
int Dim_,
int Degree_>
273 return m_knots.size() - m_ctrls.cols() - 1;
278 template <
typename Scalar_,
int Dim_,
int Degree_>
283 template <
typename Scalar_,
int Dim_,
int Degree_>
285 enum { Order = SplineTraits<Spline>::OrderAtCompileTime };
287 const DenseIndex span = this->span(u);
288 const DenseIndex p = degree();
293 return (ctrl_weights * ctrl_pts).rowwise().sum();
298 template <
typename SplineType,
typename DerivativeType>
299 void derivativesImpl(
const SplineType& spline,
typename SplineType::Scalar u, DenseIndex order, DerivativeType& der) {
300 enum { Dimension = SplineTraits<SplineType>::Dimension };
301 enum { Order = SplineTraits<SplineType>::OrderAtCompileTime };
302 enum { DerivativeOrder = DerivativeType::ColsAtCompileTime };
304 typedef typename SplineTraits<SplineType>::ControlPointVectorType ControlPointVectorType;
305 typedef typename SplineTraits<SplineType, DerivativeOrder>::BasisDerivativeType BasisDerivativeType;
306 typedef typename BasisDerivativeType::ConstRowXpr BasisDerivativeRowXpr;
308 const DenseIndex p = spline.degree();
309 const DenseIndex span = spline.span(u);
311 const DenseIndex n = (std::min)(p, order);
313 der.resize(Dimension, n + 1);
316 const BasisDerivativeType basis_func_ders = spline.template basisFunctionDerivatives<DerivativeOrder>(u, n + 1);
319 for (DenseIndex der_order = 0; der_order < n + 1; ++der_order) {
320 const Replicate<BasisDerivativeRowXpr, Dimension, 1> ctrl_weights(basis_func_ders.row(der_order));
321 const Block<const ControlPointVectorType, Dimension, Order> ctrl_pts(spline.ctrls(), 0, span - p, Dimension, p + 1);
322 der.col(der_order) = (ctrl_weights * ctrl_pts).rowwise().sum();
326 template <
typename Scalar_,
int Dim_,
int Degree_>
328 Scalar u, DenseIndex order)
const {
329 typename SplineTraits<Spline>::DerivativeType res;
330 derivativesImpl(*
this, u, order, res);
334 template <
typename Scalar_,
int Dim_,
int Degree_>
335 template <
int DerivativeOrder>
336 typename SplineTraits<Spline<Scalar_, Dim_, Degree_>, DerivativeOrder>::DerivativeType
338 typename SplineTraits<Spline, DerivativeOrder>::DerivativeType res;
339 derivativesImpl(*
this, u, order, res);
343 template <
typename Scalar_,
int Dim_,
int Degree_>
351 template <
typename Scalar_,
int Dim_,
int Degree_>
352 template <
typename DerivativeType>
357 enum { Order = SplineTraits<SplineType>::OrderAtCompileTime };
359 const DenseIndex span = SplineType::Span(u, p, U);
361 const DenseIndex n = (std::min)(p, order);
363 N_.resize(n + 1, p + 1);
365 BasisVectorType left = BasisVectorType::Zero(p + 1);
366 BasisVectorType right = BasisVectorType::Zero(p + 1);
368 Matrix<Scalar, Order, Order> ndu(p + 1, p + 1);
375 for (j = 1; j <= p; ++j) {
376 left[j] = u - U[span + 1 - j];
377 right[j] = U[span + j] - u;
380 for (DenseIndex r = 0; r < j; ++r) {
382 ndu(j, r) = right[r + 1] + left[j - r];
383 temp = ndu(r, j - 1) / ndu(j, r);
385 ndu(r, j) =
static_cast<Scalar
>(saved + right[r + 1] * temp);
386 saved = left[j - r] * temp;
389 ndu(j, j) =
static_cast<Scalar
>(saved);
392 for (j = p; j >= 0; --j) N_(0, j) = ndu(j, p);
395 DerivativeType a(n + 1, p + 1);
397 for (; r <= p; ++r) {
404 for (DenseIndex k = 1; k <= static_cast<DenseIndex>(n); ++k) {
406 DenseIndex rk, pk, j1, j2;
411 a(s2, 0) = a(s1, 0) / ndu(pk + 1, rk);
412 d = a(s2, 0) * ndu(rk, pk);
425 for (j = j1; j <= j2; ++j) {
426 a(s2, j) = (a(s1, j) - a(s1, j - 1)) / ndu(pk + 1, rk + j);
427 d += a(s2, j) * ndu(rk + j, pk);
431 a(s2, k) = -a(s1, k - 1) / ndu(pk + 1, r);
432 d += a(s2, k) * ndu(r, pk);
435 N_(k, r) =
static_cast<Scalar
>(d);
445 for (DenseIndex k = 1; k <= static_cast<DenseIndex>(n); ++k) {
446 for (j = p; j >= 0; --j) N_(k, j) *= r;
451 template <
typename Scalar_,
int Dim_,
int Degree_>
452 typename SplineTraits<Spline<Scalar_, Dim_, Degree_> >::BasisDerivativeType
455 BasisFunctionDerivativesImpl(u, order, degree(), knots(), der);
459 template <
typename Scalar_,
int Dim_,
int Degree_>
460 template <
int DerivativeOrder>
461 typename SplineTraits<Spline<Scalar_, Dim_, Degree_>, DerivativeOrder>::BasisDerivativeType
463 typename SplineTraits<Spline<Scalar_, Dim_, Degree_>, DerivativeOrder>::BasisDerivativeType der;
464 BasisFunctionDerivativesImpl(u, order, degree(), knots(), der);
468 template <
typename Scalar_,
int Dim_,
int Degree_>
469 typename SplineTraits<Spline<Scalar_, Dim_, Degree_> >::BasisDerivativeType
473 typename SplineTraits<Spline>::BasisDerivativeType der;
474 BasisFunctionDerivativesImpl(u, order, degree, knots, der);
479 #endif // EIGEN_SPLINE_H A class representing multi-dimensional spline curves.
Definition: Spline.h:37
PointType operator()(Scalar u) const
Returns the spline value at a given site .
Definition: Spline.h:284
SplineTraits< Spline >::BasisDerivativeType BasisDerivativeType
The data type used to store the values of the basis function derivatives.
Definition: Spline.h:56
SplineTraits< Spline >::BasisVectorType basisFunctions(Scalar u) const
Computes the non-zero basis functions at the given site.
Definition: Spline.h:344
DenseIndex degree() const
Returns the spline degree.
Definition: Spline.h:271
const KnotVectorType & knots() const
Returns the knots of the underlying spline.
Definition: Spline.h:93
Scalar_ Scalar
Definition: Spline.h:39
SplineTraits< Spline >::ParameterVectorType ParameterVectorType
The data type used to store parameter vectors.
Definition: Spline.h:50
Namespace containing all symbols from the Eigen library.
SplineTraits< Spline >::BasisVectorType BasisVectorType
The data type used to store non-zero basis functions.
Definition: Spline.h:53
Spline(const OtherVectorType &knots, const OtherArrayType &ctrls)
Creates a spline from a knot vector and control points.
Definition: Spline.h:81
SplineTraits< Spline >::PointType PointType
The point type the spline is representing.
Definition: Spline.h:44
Spline(const Spline< Scalar, Dimension, OtherDegree > &spline)
Copy constructor for splines.
Definition: Spline.h:88
DenseIndex span(Scalar u) const
Returns the span within the knot vector in which u is falling.
Definition: Spline.h:279
SplineTraits< Spline >::DerivativeType derivatives(Scalar u, DenseIndex order) const
Evaluation of spline derivatives of up-to given order.
Definition: Spline.h:327
SplineTraits< Spline >::BasisDerivativeType basisFunctionDerivatives(Scalar u, DenseIndex order) const
Computes the non-zero spline basis function derivatives up to given order.
Definition: Spline.h:453
static DenseIndex Span(typename SplineTraits< Spline >::Scalar u, DenseIndex degree, const typename SplineTraits< Spline >::KnotVectorType &knots)
Computes the span within the provided knot vector in which u is falling.
Definition: Spline.h:229
SplineTraits< Spline >::KnotVectorType KnotVectorType
The data type used to store knot vectors.
Definition: Spline.h:47
static BasisDerivativeType BasisFunctionDerivatives(const Scalar u, const DenseIndex order, const DenseIndex degree, const KnotVectorType &knots)
Computes the non-zero spline basis function derivatives up to given order.
Definition: Spline.h:470
SplineTraits< Spline >::ControlPointVectorType ControlPointVectorType
The data type representing the spline's control points.
Definition: Spline.h:59
static BasisVectorType BasisFunctions(Scalar u, DenseIndex degree, const KnotVectorType &knots)
Returns the spline's non-zero basis functions.
Definition: Spline.h:239
Spline()
Creates a (constant) zero spline. For Splines with dynamic degree, the resulting degree will be 0...
Definition: Spline.h:65
const ControlPointVectorType & ctrls() const
Returns the ctrls of the underlying spline.
Definition: Spline.h:98