在分段三次Bézier路径中插入点的算法

时间:2010-04-10 14:57:57

标签: algorithm vector-graphics bezier

我正在寻找一种算法,在Bézier曲线上插入一个新的控制点,而不会变形。

有人知道Bézier算法的库或参考(插入,优化,de Casteljau ......)?

3 个答案:

答案 0 :(得分:22)

这称为“结插入问题”。对于Bézier曲线,de Casteljau算法将为您提供正确的答案。这是3度贝塞尔的简单算法。

假设您要在由t定义的Bézier曲线内的参数空间的分数P0, P1, P2, P3处插入一个结。这是你做的:

P0_1 = (1-t)*P0 + t*P1
P1_2 = (1-t)*P1 + t*P2
P2_3 = (1-t)*P2 + t*P3

P01_12 = (1-t)*P0_1 + t*P1_2
P12_23 = (1-t)*P1_2 + t*P2_3

P0112_1223 = (1-t)*P01_12 + t*P12_23

然后你的第一个Bézier将被定义为:P_0, P0_1, P01_12, P0112_1223;你的第二个Bézier定义为:P0112_1223, P12_23, P2_3, P3

几何解释很简单:在分数t处分割Bézier多边形的每个分段,然后将这些分割点连接到一个新的多边形并迭代。当您离开1点时,此点位于曲线上,前一个/下一个分割点形成前一个/下一个Bézier多边形。相同的算法也适用于更高度的Bézier曲线。

现在,如果您想要将控制点插入到t的特定值但是在空间中的特定位置,则会变得更加棘手。就个人而言,我在这里做的只是二进制搜索t的值接近所需的分裂点...但如果性能至关重要,你可能会找到一个更快的分析解决方案。

答案 1 :(得分:2)

您也可以采用数学方法。

具有控制点p_1,p_2,p_3,p_4的qubicBézier曲线可写为:

b(t)=(1-t)^3 p_1+3t(1-t)^2 p_2+3t^2 (1-t) p_3+t^3 p_4

其衍生物w.r.t. t

\frac{\partial b}{\partial t} = 3(1-t)^2 (p_2-p_1 )+6t(1-t)(p_3-p_2 )+3t^2 (p_4-p_3 )

要将曲线从t0限制为t1,您将获得新的控制点q_1,q_2,q_3,q_4

q_1=b(t_0),q_4=b(t_1)

q_2=q_1+\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_0)}

q_3=q_4-\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_1)}

证明

s=\frac{t-t_0}{t_1-t_0}

t=t_0+s(t_1-t_0 )

我们得到了

\frac{\partial b}{\partial s} = \frac{\partial b}{\partial t} \frac{\partial t}{\partial s} = (t_1-t_0) \frac{\partial b}{\partial t}

子曲线的第一个和最后一个点是第一个和最后一个新控制点

q_1=b(t_0),q_4=b(t_1)

这些点的切线是

\frac{\partial{b}}{\partial{s}}_{(s=0)}=(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_0)}=3(q_2-q_1)

\frac{\partial{b}}{\partial{s}}_{(s=1)}=(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_1)}=3(q_4-q_3)

所以

q_2=q_1+\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_0)}

q_3=q_4-\frac{1}{3}(t_1-t_0)\frac{\partial{b}}{\partial{t}}_{(t=t_1)}

答案 2 :(得分:1)

为完整性添加此内容。

可以在GIMP内的gimpbezierstroke.c源代码中找到许多Bézier路径操作的开源实现。有关插入新锚点的参考,请搜索gimp_bezier_stroke_anchor_insert