Math 拆分一个三次Bé;点上的齐尔曲线

Math 拆分一个三次Bé;点上的齐尔曲线,math,geometry,computational-geometry,bezier,cubic-bezier,Math,Geometry,Computational Geometry,Bezier,Cubic Bezier,两者都显示了如何在特定的参数化值为0时分割三次Bézier曲线≤ T≤ 1沿曲线,由两个新线段组成原始曲线形状。我需要在我知道坐标的曲线上的一个点上分割我的Bézier曲线,但不是该点的参数化值t 例如,考虑Adobe Idultor,用户可以点击曲线在路径中添加一个点,而不影响路径的形状。 假设我最接近用户单击的位置,我如何从中计算控制点?给定曲线上的一个点,是否有一个公式来分割Bézier曲线 或者(且不太理想),给定曲线上的一个点,是否有方法确定对应于该点的参数化值t(除了在二进制搜索中使

两者都显示了如何在特定的参数化值为0时分割三次Bézier曲线≤ T≤ 1沿曲线,由两个新线段组成原始曲线形状。我需要在我知道坐标的曲线上的一个点上分割我的Bézier曲线,但不是该点的参数化值t

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

假设我最接近用户单击的位置,我如何从中计算控制点?给定曲线上的一个点,是否有一个公式来分割Bézier曲线

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



我的Bézier曲线恰好是二维的,但一个很好的答案将包括适用于任意维的向量数学。

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

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

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

其中,bx(t)是指具有控制点x0、x1、x2和x3的多项式形式的某些贝塞尔曲线的x分量,bx’(t)是一阶导数,cx是曲线上的一个点,因此:

cx=bx(t)| 0 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-x0)|x0 现在您已经拥有:

bx(tn)≈ cx

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

注意,Newton-Raphson算法具有二次收敛性。在大多数情况下,良好的起始值将在两次迭代后产生可忽略的改善,即小于半个像素


最后值得注意的是,三次Bezier曲线通过求一阶导数的根来精确求解极值。因此,有问题的曲线可以简单地在其极值处细分,以消除回路或尖点,然后通过分析所产生的有问题的截面可以获得更好的结果。以这种方式细分立方体将满足上述约束。

IIRC和a在插入参数值并获得坐标的地方,可以(理论上)计算逆矩阵并使用它,也许吧。找到曲线上最近的点需要确定t值。准确地找到最近的点并不那么简单,因为它需要在2D中求解一个六次多项式。但是你也可以在屏幕空间里做。绘制曲线时,将相应的t值绘制到单独的缓冲区。然后,您只需进行屏幕空间最近点搜索,即可立即知道参数。顺便说一句,对参数的二进制搜索也不起作用,因为三次曲线中的坐标不是单调的。@NicoSchertler我怀疑二进制搜索会失败。是的。很多地方都不完美。在我的例子中,其他人(web浏览器SVG)正在绘制曲线,因此我必须自己绘制曲线以找到最接近的曲线。问题是,SVG坐标并不总是像素,所以我必须仔细选择行进的大小,以平衡性能和精度。谢谢你的意见。好消息:使用此方法找到点后,我还将使用t值进行分割。我建议您阅读Pomax关于Bézier曲线的综合书籍,可能交点和根查找将帮助您获得四次曲线:。不过我认为你最好使用de Casteljau和二进制搜索,这对任何程度的Bézier曲线都有效。