mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-04 18:54:00 +08:00
Added spline interpolation with pre-defined knot parameters.
This commit is contained in:
parent
f6a5508392
commit
84c93b048e
@ -102,38 +102,53 @@ namespace Eigen
|
|||||||
template <typename SplineType>
|
template <typename SplineType>
|
||||||
struct SplineFitting
|
struct SplineFitting
|
||||||
{
|
{
|
||||||
|
typedef typename SplineType::KnotVectorType KnotVectorType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Fits an interpolating Spline to the given data points.
|
* \brief Fits an interpolating Spline to the given data points.
|
||||||
|
*
|
||||||
|
* \param pts The points for which an interpolating spline will be computed.
|
||||||
|
* \param degree The degree of the interpolating spline.
|
||||||
|
*
|
||||||
|
* \returns A spline interpolating the initially provided points.
|
||||||
**/
|
**/
|
||||||
template <typename PointArrayType>
|
template <typename PointArrayType>
|
||||||
static SplineType Interpolate(const PointArrayType& pts, DenseIndex degree);
|
static SplineType Interpolate(const PointArrayType& pts, DenseIndex degree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Fits an interpolating Spline to the given data points.
|
||||||
|
*
|
||||||
|
* \param pts The points for which an interpolating spline will be computed.
|
||||||
|
* \param degree The degree of the interpolating spline.
|
||||||
|
* \param knot_parameters The knot parameters for the interpolation.
|
||||||
|
*
|
||||||
|
* \returns A spline interpolating the initially provided points.
|
||||||
|
**/
|
||||||
|
template <typename PointArrayType>
|
||||||
|
static SplineType Interpolate(const PointArrayType& pts, DenseIndex degree, const KnotVectorType& knot_parameters);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename SplineType>
|
template <typename SplineType>
|
||||||
template <typename PointArrayType>
|
template <typename PointArrayType>
|
||||||
SplineType SplineFitting<SplineType>::Interpolate(const PointArrayType& pts, DenseIndex degree)
|
SplineType SplineFitting<SplineType>::Interpolate(const PointArrayType& pts, DenseIndex degree, const KnotVectorType& knot_parameters)
|
||||||
{
|
{
|
||||||
typedef typename SplineType::KnotVectorType::Scalar Scalar;
|
typedef typename SplineType::KnotVectorType::Scalar Scalar;
|
||||||
typedef typename SplineType::KnotVectorType KnotVectorType;
|
|
||||||
typedef typename SplineType::BasisVectorType BasisVectorType;
|
typedef typename SplineType::BasisVectorType BasisVectorType;
|
||||||
typedef typename SplineType::ControlPointVectorType ControlPointVectorType;
|
typedef typename SplineType::ControlPointVectorType ControlPointVectorType;
|
||||||
|
|
||||||
typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
|
typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
|
||||||
|
|
||||||
KnotVectorType chord_lengths; // knot parameters
|
|
||||||
ChordLengths(pts, chord_lengths);
|
|
||||||
|
|
||||||
KnotVectorType knots;
|
KnotVectorType knots;
|
||||||
KnotAveraging(chord_lengths, degree, knots);
|
KnotAveraging(knot_parameters, degree, knots);
|
||||||
|
|
||||||
DenseIndex n = pts.cols();
|
DenseIndex n = pts.cols();
|
||||||
MatrixType A = MatrixType::Zero(n,n);
|
MatrixType A = MatrixType::Zero(n,n);
|
||||||
for (DenseIndex i=1; i<n-1; ++i)
|
for (DenseIndex i=1; i<n-1; ++i)
|
||||||
{
|
{
|
||||||
const DenseIndex span = SplineType::Span(chord_lengths[i], degree, knots);
|
const DenseIndex span = SplineType::Span(knot_parameters[i], degree, knots);
|
||||||
|
|
||||||
// The segment call should somehow be told the spline order at compile time.
|
// The segment call should somehow be told the spline order at compile time.
|
||||||
A.row(i).segment(span-degree, degree+1) = SplineType::BasisFunctions(chord_lengths[i], degree, knots);
|
A.row(i).segment(span-degree, degree+1) = SplineType::BasisFunctions(knot_parameters[i], degree, knots);
|
||||||
}
|
}
|
||||||
A(0,0) = 1.0;
|
A(0,0) = 1.0;
|
||||||
A(n-1,n-1) = 1.0;
|
A(n-1,n-1) = 1.0;
|
||||||
@ -145,6 +160,15 @@ namespace Eigen
|
|||||||
|
|
||||||
return SplineType(knots, ctrls);
|
return SplineType(knots, ctrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SplineType>
|
||||||
|
template <typename PointArrayType>
|
||||||
|
SplineType SplineFitting<SplineType>::Interpolate(const PointArrayType& pts, DenseIndex degree)
|
||||||
|
{
|
||||||
|
KnotVectorType chord_lengths; // knot parameters
|
||||||
|
ChordLengths(pts, chord_lengths);
|
||||||
|
return Interpolate(pts, degree, chord_lengths);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_SPLINE_FITTING_H
|
#endif // EIGEN_SPLINE_FITTING_H
|
||||||
|
@ -216,16 +216,32 @@ void check_global_interpolation2d()
|
|||||||
typedef Spline2d::ControlPointVectorType ControlPointVectorType;
|
typedef Spline2d::ControlPointVectorType ControlPointVectorType;
|
||||||
|
|
||||||
ControlPointVectorType points = ControlPointVectorType::Random(2,100);
|
ControlPointVectorType points = ControlPointVectorType::Random(2,100);
|
||||||
const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3);
|
|
||||||
|
|
||||||
KnotVectorType chord_lengths; // knot parameters
|
KnotVectorType chord_lengths; // knot parameters
|
||||||
Eigen::ChordLengths(points, chord_lengths);
|
Eigen::ChordLengths(points, chord_lengths);
|
||||||
|
|
||||||
for (Eigen::DenseIndex i=0; i<points.cols(); ++i)
|
// interpolation without knot parameters
|
||||||
{
|
{
|
||||||
PointType pt = spline( chord_lengths(i) );
|
const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3);
|
||||||
PointType ref = points.col(i);
|
|
||||||
VERIFY( (pt - ref).matrix().norm() < 1e-14 );
|
for (Eigen::DenseIndex i=0; i<points.cols(); ++i)
|
||||||
|
{
|
||||||
|
PointType pt = spline( chord_lengths(i) );
|
||||||
|
PointType ref = points.col(i);
|
||||||
|
VERIFY( (pt - ref).matrix().norm() < 1e-14 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interpolation with given knot parameters
|
||||||
|
{
|
||||||
|
const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3,chord_lengths);
|
||||||
|
|
||||||
|
for (Eigen::DenseIndex i=0; i<points.cols(); ++i)
|
||||||
|
{
|
||||||
|
PointType pt = spline( chord_lengths(i) );
|
||||||
|
PointType ref = points.col(i);
|
||||||
|
VERIFY( (pt - ref).matrix().norm() < 1e-14 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user