Spline and spline fitting module

Classes

class  Eigen::Spline< Scalar_, Dim_, Degree_ >
 A class representing multi-dimensional spline curves. More...
 
struct  Eigen::SplineFitting< SplineType >
 Spline fitting methods. More...
 
struct  Eigen::SplineTraits< Spline< Scalar_, Dim_, Degree_ >, _DerivativeOrder >
 Compile-time attributes of the Spline class for fixed degree. More...
 
struct  Eigen::SplineTraits< Spline< Scalar_, Dim_, Degree_ >, Dynamic >
 Compile-time attributes of the Spline class for Dynamic degree. More...
 

Functions

template<typename PointArrayType , typename KnotVectorType >
void Eigen::ChordLengths (const PointArrayType &pts, KnotVectorType &chord_lengths)
 Computes chord length parameters which are required for spline interpolation. More...
 
template<typename KnotVectorType >
void Eigen::KnotAveraging (const KnotVectorType &parameters, DenseIndex degree, KnotVectorType &knots)
 Computes knot averages. More...
 
template<typename KnotVectorType , typename ParameterVectorType , typename IndexArray >
void Eigen::KnotAveragingWithDerivatives (const ParameterVectorType &parameters, const unsigned int degree, const IndexArray &derivativeIndices, KnotVectorType &knots)
 Computes knot averages when derivative constraints are present. Note that this is a technical interpretation of the referenced article since the algorithm contained therein is incorrect as written. More...
 

Detailed Description

This module provides a simple multi-dimensional spline class while offering most basic functionality to fit a spline to point sets.

Function Documentation

◆ ChordLengths()

template<typename PointArrayType , typename KnotVectorType >
void Eigen::ChordLengths ( const PointArrayType &  pts,
KnotVectorType &  chord_lengths 
)

Computes chord length parameters which are required for spline interpolation.

Parameters
[in]ptsThe data points to which a spline should be fit.
[out]chord_lengthsThe resulting chord length vector.
See also
Les Piegl and Wayne Tiller, The NURBS book (2nd ed.), 1997, 9.2.1 Global Curve Interpolation to Point Data

Definition at line 192 of file SplineFitting.h.

193  {
194  typedef typename KnotVectorType::Scalar Scalar;
195 
196  const DenseIndex n = pts.cols();
197 
198  // 1. compute the column-wise norms
199  chord_lengths.resize(pts.cols());
200  chord_lengths[0] = 0;
201  chord_lengths.rightCols(n-1) = (pts.array().leftCols(n-1) - pts.array().rightCols(n-1)).matrix().colwise().norm();
202 
203  // 2. compute the partial sums
204  std::partial_sum(chord_lengths.data(), chord_lengths.data()+n, chord_lengths.data());
205 
206  // 3. normalize the data
207  chord_lengths /= chord_lengths(n-1);
208  chord_lengths(n-1) = Scalar(1);
209  }
int n
EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex

◆ KnotAveraging()

template<typename KnotVectorType >
void Eigen::KnotAveraging ( const KnotVectorType &  parameters,
DenseIndex  degree,
KnotVectorType &  knots 
)

Computes knot averages.

The knots are computed as

\begin{align*} u_0 & = \hdots = u_p = 0 \\ u_{m-p} & = \hdots = u_{m} = 1 \\ u_{j+p} & = \frac{1}{p}\sum_{i=j}^{j+p-1}\bar{u}_i \quad\quad j=1,\hdots,n-p \end{align*}

where \(p\) is the degree and \(m+1\) the number knots of the desired interpolating spline.

Parameters
[in]parametersThe input parameters. During interpolation one for each data point.
[in]degreeThe spline degree which is used during the interpolation.
[out]knotsThe output knot vector.
See also
Les Piegl and Wayne Tiller, The NURBS book (2nd ed.), 1997, 9.2.1 Global Curve Interpolation to Point Data

Definition at line 48 of file SplineFitting.h.

49  {
50  knots.resize(parameters.size()+degree+1);
51 
52  for (DenseIndex j=1; j<parameters.size()-degree; ++j)
53  knots(j+degree) = parameters.segment(j,degree).mean();
54 
55  knots.segment(0,degree+1) = KnotVectorType::Zero(degree+1);
56  knots.segment(knots.size()-degree-1,degree+1) = KnotVectorType::Ones(degree+1);
57  }
std::ptrdiff_t j

◆ KnotAveragingWithDerivatives()

template<typename KnotVectorType , typename ParameterVectorType , typename IndexArray >
void Eigen::KnotAveragingWithDerivatives ( const ParameterVectorType &  parameters,
const unsigned int  degree,
const IndexArray &  derivativeIndices,
KnotVectorType &  knots 
)

Computes knot averages when derivative constraints are present. Note that this is a technical interpretation of the referenced article since the algorithm contained therein is incorrect as written.

Parameters
[in]parametersThe parameters at which the interpolation B-Spline will intersect the given interpolation points. The parameters are assumed to be a non-decreasing sequence.
[in]degreeThe degree of the interpolating B-Spline. This must be greater than zero.
[in]derivativeIndicesThe indices corresponding to parameters at which there are derivative constraints. The indices are assumed to be a non-decreasing sequence.
[out]knotsThe calculated knot vector. These will be returned as a non-decreasing sequence
See also
Les A. Piegl, Khairan Rajab, Volha Smarodzinana. 2008. Curve interpolation with directional constraints for engineering design. Engineering with Computers

Definition at line 81 of file SplineFitting.h.

85  {
86  typedef typename ParameterVectorType::Scalar Scalar;
87 
88  DenseIndex numParameters = parameters.size();
89  DenseIndex numDerivatives = derivativeIndices.size();
90 
91  if (numDerivatives < 1)
92  {
93  KnotAveraging(parameters, degree, knots);
94  return;
95  }
96 
97  DenseIndex startIndex;
98  DenseIndex endIndex;
99 
100  DenseIndex numInternalDerivatives = numDerivatives;
101 
102  if (derivativeIndices[0] == 0)
103  {
104  startIndex = 0;
105  --numInternalDerivatives;
106  }
107  else
108  {
109  startIndex = 1;
110  }
111  if (derivativeIndices[numDerivatives - 1] == numParameters - 1)
112  {
113  endIndex = numParameters - degree;
114  --numInternalDerivatives;
115  }
116  else
117  {
118  endIndex = numParameters - degree - 1;
119  }
120 
121  // There are (endIndex - startIndex + 1) knots obtained from the averaging
122  // and 2 for the first and last parameters.
123  DenseIndex numAverageKnots = endIndex - startIndex + 3;
124  KnotVectorType averageKnots(numAverageKnots);
125  averageKnots[0] = parameters[0];
126 
127  int newKnotIndex = 0;
128  for (DenseIndex i = startIndex; i <= endIndex; ++i)
129  averageKnots[++newKnotIndex] = parameters.segment(i, degree).mean();
130  averageKnots[++newKnotIndex] = parameters[numParameters - 1];
131 
132  newKnotIndex = -1;
133 
134  ParameterVectorType temporaryParameters(numParameters + 1);
135  KnotVectorType derivativeKnots(numInternalDerivatives);
136  for (DenseIndex i = 0; i < numAverageKnots - 1; ++i)
137  {
138  temporaryParameters[0] = averageKnots[i];
139  ParameterVectorType parameterIndices(numParameters);
140  int temporaryParameterIndex = 1;
141  for (DenseIndex j = 0; j < numParameters; ++j)
142  {
143  Scalar parameter = parameters[j];
144  if (parameter >= averageKnots[i] && parameter < averageKnots[i + 1])
145  {
146  parameterIndices[temporaryParameterIndex] = j;
147  temporaryParameters[temporaryParameterIndex++] = parameter;
148  }
149  }
150  temporaryParameters[temporaryParameterIndex] = averageKnots[i + 1];
151 
152  for (int j = 0; j <= temporaryParameterIndex - 2; ++j)
153  {
154  for (DenseIndex k = 0; k < derivativeIndices.size(); ++k)
155  {
156  if (parameterIndices[j + 1] == derivativeIndices[k]
157  && parameterIndices[j + 1] != 0
158  && parameterIndices[j + 1] != numParameters - 1)
159  {
160  derivativeKnots[++newKnotIndex] = temporaryParameters.segment(j, 3).mean();
161  break;
162  }
163  }
164  }
165  }
166 
167  KnotVectorType temporaryKnots(averageKnots.size() + derivativeKnots.size());
168 
169  std::merge(averageKnots.data(), averageKnots.data() + averageKnots.size(),
170  derivativeKnots.data(), derivativeKnots.data() + derivativeKnots.size(),
171  temporaryKnots.data());
172 
173  // Number of knots (one for each point and derivative) plus spline order.
174  DenseIndex numKnots = numParameters + numDerivatives + degree + 1;
175  knots.resize(numKnots);
176 
177  knots.head(degree).fill(temporaryKnots[0]);
178  knots.tail(degree).fill(temporaryKnots.template tail<1>()[0]);
179  knots.segment(degree, temporaryKnots.size()) = temporaryKnots;
180  }
int i
void KnotAveraging(const KnotVectorType &parameters, DenseIndex degree, KnotVectorType &knots)
Computes knot averages.
Definition: SplineFitting.h:48