特征样条插值 - 如何在仲裁点x处获得样条y值?

win*_*rgy 2 c++ spline eigen3

我尝试使用Eigen库来创建样条曲线.但是,一旦我创建样条曲线,我就不知道如何得到给定点x的值.

请参阅下面的示例,并解释我的意图:

#include <Eigen/Core>
#include <unsupported/Eigen/Splines>

int main(int argc, char const* argv[])
{
    // points at (0,0) (15,12) and (30,17)
    Eigen::MatrixXd points(2, 3);
    points << 0, 15, 30,
              0, 12, 17;

    typedef Eigen::Spline<double, 2> spline2d;
    spline2d s = Eigen::SplineFitting<spline2d>::Interpolate(points, 2);

    // I now have a spline called s.
    // I want to do something like:
    double x = 12.34;
    double new_y = s(x)[1];  // However this s() function uses a chord value. What is a chord value?

    // Is there a:
    double new_y2 = s.eval(x)
}
Run Code Online (Sandbox Code Playgroud)

Win*_*ute 11

我知道这可能会让人感到困惑.当您使用Eigen Spline拟合模块时,它不会对函数R - > R进行建模.例如,您可以使用它构建螺旋线.这意味着你不能期望从X值获得Y值,而是在样条曲线上选择它们沿着样条曲线的距离(因此是弦长).

可以使用模块对函数建模,虽然不是非常直观:考虑你的Y值在R 1中,而不是让Eigen计算弦长,而是提供你自己的一组结点参数,它们的间距就像你的X值一样(缩小到[0,1],因此算法可以应对).它可以打包这样的东西:

#include <Eigen/Core>
#include <unsupported/Eigen/Splines>

#include <iostream>

class SplineFunction {
public:
  SplineFunction(Eigen::VectorXd const &x_vec,
                 Eigen::VectorXd const &y_vec)
    : x_min(x_vec.minCoeff()),
      x_max(x_vec.maxCoeff()),
      // Spline fitting here. X values are scaled down to [0, 1] for this.
      spline_(Eigen::SplineFitting<Eigen::Spline<double, 1>>::Interpolate(
                y_vec.transpose(),
                 // No more than cubic spline, but accept short vectors.

                std::min<int>(x_vec.rows() - 1, 3),
                scaled_values(x_vec)))
  { }

  double operator()(double x) const {
    // x values need to be scaled down in extraction as well.
    return spline_(scaled_value(x))(0);
  }

private:
  // Helpers to scale X values down to [0, 1]
  double scaled_value(double x) const {
    return (x - x_min) / (x_max - x_min);
  }

  Eigen::RowVectorXd scaled_values(Eigen::VectorXd const &x_vec) const {
    return x_vec.unaryExpr([this](double x) { return scaled_value(x); }).transpose();
  }

  double x_min;
  double x_max;

  // Spline of one-dimensional "points."
  Eigen::Spline<double, 1> spline_;
};

int main(int argc, char const* argv[])
{
  Eigen::VectorXd xvals(3);
  Eigen::VectorXd yvals(xvals.rows());

  xvals << 0, 15, 30;
  yvals << 0, 12, 17;

  SplineFunction s(xvals, yvals);

  std::cout << s(12.34) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)