在点

时间:2017-07-08 23:39:33

标签: math geometry computational-geometry bezier cubic-bezier

This questionthis question都显示如何沿着曲线在特定参数化值0≤ t ≤1处拆分三次Bézier曲线,组成原始曲线形状两个新细分。我需要将Bézier曲线分割为曲线上我知道坐标的点,而不是该点的参数化值 t

例如,考虑Adobe Illustrator,用户可以在其中单击曲线以在路径中添加点,而不会影响路径的形状。

假设我find the point on the curve最接近用户点击的位置,我该如何计算控制点呢?给出曲线上的一个点,是否存在分割Bézier曲线的公式?

或者(并且不太理想),给定曲线上的点,是否有一种方法来确定对应于该点的参数化值 t (除了在二元搜索中使用De Casteljau的算法) ?

我的Bézier曲线恰好只是2D,但一个很好的答案将包括在任意维度上应用的矢量数学。

1 个答案:

答案 0 :(得分:1)

在不使用 De Casteljau 算法的情况下确定曲线上某个点的参数值是可能的,而且可能更简单,但您必须使用启发式方法来找到一个好的起始值并类似地近似结果。

一种可能且相当简单的方法是使用牛顿法:

tn+1 = tn - ( bx(tn) - cx ) / bx'(tn)

其中bx(t)指的是控制点为x的多项式形式的贝塞尔曲线的x分量0x1x2 x3, bx'(t) 是一阶导数,cx 是曲线上的一个点,满足:

cx = bx(t) | 0 < t < 1

bx(t) 的系数为:

A = -x0 + 3x1 - 3x2 + x3
B = 3x0 - 6x1 + 3x2
C = -3x0 + 3x1
D = x0

和:

bx(t) = At3 + Bt2 + Ct + D,
bx'(t) = 3At2 + 2Bt + C

现在找到一个好的起始值来插入牛顿的方法是棘手的部分。对于大多数不包含环或尖点的曲线,您可以简单地使用以下公式:

tn = ( cx - x0 ) / ( x3 - x 0 ) | x0 < x1 < x2 < x3

现在您已经拥有:

bx(tn) ≈ cx

因此,应用牛顿法的一次或多次迭代将为 cx 提供更好的 t 近似值。

请注意,Newton Raphson 算法具有二次收敛性。在大多数情况下,一个好的起始值在两次迭代后会导致可以忽略不计的改进,即不到半个像素。

最后值得注意的是三次贝塞尔曲线具有通过求一阶导数的根来求极值的精确解。因此,可以简单地在极值处细分有问题的曲线以去除环或尖点,然后通过分析有问题的结果部分可以获得更好的结果。以这种方式细分三次方将满足上述约束。