Algorithm 从沿贝塞尔曲线的点导出贝塞尔曲线控制点的算法?

Algorithm 从沿贝塞尔曲线的点导出贝塞尔曲线控制点的算法?,algorithm,bezier,Algorithm,Bezier,我一直在寻找,但显然没有找到一种算法,它允许我插入一个已知沿曲线的x,y坐标列表,以便得到三次贝塞尔曲线的4个控制点 更准确地说,我正在寻找一种算法,该算法在输入一系列离散点(包括确定曲线起点和终点的两个控制点)的同时,为我提供塑造曲线所需的两个控制点 谢谢 编辑:好的,由于数学,一个老对手,我需要求多项式函数的最佳拟合贝塞尔曲线。所以我假设端点是固定的,然后你有一些(x,y)采样点,你想用三次贝塞尔拟合 您拥有的采样点数量将决定采取何种方法。让我们看几个案例: 2分 2个采样点是最简单的情况。

我一直在寻找,但显然没有找到一种算法,它允许我插入一个已知沿曲线的x,y坐标列表,以便得到三次贝塞尔曲线的4个控制点

更准确地说,我正在寻找一种算法,该算法在输入一系列离散点(包括确定曲线起点和终点的两个控制点)的同时,为我提供塑造曲线所需的两个控制点

谢谢


编辑:好的,由于数学,一个老对手,我需要求多项式函数的最佳拟合贝塞尔曲线。

所以我假设端点是固定的,然后你有一些(x,y)采样点,你想用三次贝塞尔拟合

您拥有的采样点数量将决定采取何种方法。让我们看几个案例:

2分

2个采样点是最简单的情况。如果算上终点的话,你总共得4分。这是立方贝塞尔曲线中CV的数量。要解决此问题,两个采样点都需要一个参数(t)值。然后你有一个由2个方程和2个点组成的系统,你需要求解,其中方程是贝塞尔曲线在你选择的t值处的参数方程

t值可以是您喜欢的任何值,但是您可以使用1/3和2/3,或者查看相对距离,或者沿基线的相对距离,这取决于您的数据,从而获得更好的结果

1分

这类似于2点,只是您没有足够的信息来唯一确定所有自由度。我的建议是拟合一个二次贝塞尔曲线,然后将其提升。我在年写了一个二次拟合的详细例子

超过2分

在这种情况下,没有唯一的解决方案。我使用了最小二乘近似法,效果很好。这些步骤是:

  • 为每个样本选取t值
  • 把你的方程组建立成一个矩阵
  • 可选择添加光顺或其他平滑功能
  • 使用最小二乘解算器求解矩阵

第11章对这些步骤进行了详细描述。它谈到拟合b样条曲线,但三次贝塞尔曲线是b样条曲线的一种(节点向量为0,0,0,1,1,1,有4个点)。

假设有一条曲线y=f(x)

要定义贝塞尔曲线,需要4个点,如: P1x、P1y、P2x、P2y、P3x、P3y和P4x及P4y

P1和P4是曲线的起点/终点。P2和P3是控制点。 您已经知道曲线的起点和终点在哪里。你必须计算P2和P3。x坐标P2x和P3x很容易,因为您只需通过选择曲线的
t
为eg 1/3和2/3来拾取它们。所以你有P2x和P3x 然后,你会得到一个由两个方程和两个未知数组成的系统(P2y和P3y)。 在完成一些数学运算后,你会得到如下结果:

(我的f(x)是一个三次多项式,这也保证了我能够精确地拟合一条三次贝塞尔曲线。)


谢谢你的快速回答。我认为代数可能是必需的,但考虑到曲线可能有数千个点,这可能有点淫秽。我将尝试将大曲线分解为小曲线,并应用两点法。如果这不起作用,我会给大于两点的尝试!如果曲线的精确性不太重要,您可以尝试只拾取两个点,然后使用两点法:)我的目标是一个体面的娱乐边缘孤立与索贝尔算子,所以准确度将是非常可取的。
/**
    @params {Object} firstPoint = {x:...,y...}
    @params {Object} lastPoint = {x:...,y...}
    @params {Object} cubicPoly Definition of a cubic polynomial in the form  y=ax^3+bx^2+c. 
  Has a method EvaluateAt, which calculates y for a particular x

*/
var CalcBezierControlPoints = function(firstPoint, lastPoint, cubicPoly) {
    var xDiff = lastPoint.X - firstPoint.X;
    var x1 = firstPoint.X + xDiff / 3.0;
    var x2 = firstPoint.X + 2.0 * xDiff / 3.0;

    var y1 = cubicPoly.EvaluateAt(x1);
    var y2 = cubicPoly.EvaluateAt(x2);

    var f1 = 0.296296296296296296296; // (1-1/3)^3
    var f2 = 0.037037037037037037037; // (1-2/3)^3
    var f3 = 0.296296296296296296296; // (2/3)^3

    var b1 = y1 - firstPoint.Y * f1 - lastPoint.Y / 27.0;
    var b2 = y2 - firstPoint.Y * f2 - f3 * lastPoint.Y;

    var c1 = (-2 * b1 + b2) / -0.666666666666666666;
    var c2 = (b2 - 0.2222222222222 * c1) / 0.44444444444444444;

    var p2 = {};
    var p3 = {};
    p2.X = x1;
    p2.Y = c1;

    p3.X = x2;
    p3.Y = c2;

    return ([p2, p3]);
}