有多种方法可以完成您所看到的内容,具体取决于您希望它的行为方式。我将解释一些通过点对曲线操作来修改贝塞尔曲线的更简单方法。
首先要做的是找出用户点击曲线的参数值(t)。这通常是一个近似值。如果您正在对 Bezier 进行像素或子像素渲染,那么只需记录每个像素的 t 值并使用它。如果要细分成线段,看哪条线段最近,找到两个端点的 t 值,根据沿线的距离调整 t 值。
获得 t 值后,您可以将其代入贝塞尔曲线方程。你最终会得到以下形式的东西:
P = k0*P0 + k1*P1 + k2*P2 + k3*P3
其中 P 是曲线上的点,P0、P1、P2 和 P3 是输入控制点,k0、k1、k2 和 k3 是给定 t 的常数。我将 k 值称为“贡献”,或者更具体地说,控制点对曲线 P(t) 上的点的贡献。要记住的一个很好的属性是 k0+k1+k2+k3 = 1。
因此,假设您有一个向量 V = P' - P,其中 P' 是新位置,P 是原始位置。我们需要移动一些控制点以使 P' 到达它需要去的地方,但是对于我们想要移动哪些控制点,我们有一些灵活性。任何非零贡献的点都可以使用,或者某种组合。
假设用户在 t=0 时点击了曲线。在这种情况下,只有 k0 是非零的,所以
P0 := P0 + V
会产生正确的结果。这也可以写成
P0 := P0 + k0 * V
在所有贡献都非零的一般情况下,您可以对每个点应用相同的变换,这将产生非常平滑、展开的变形效果。
另一种选择是简单地将控制点以最大贡献移动整个距离。我认为要使用的方程式类似于
Pmax := Pmax + 1/kmax * V
但无论哪种方式,它都归结为查看给定 t 值的贡献,并移动控制点,使新点位于所需位置。
这种方法相当通用,适用于 NURBS 和大多数其他样条线,甚至是曲面。还有另一种相当常见的方法,它使用 Greville Abscissae,它尽可能多地固定点,但根据我的经验,它太容易产生振荡。