[iOS Objective C]从闭合贝塞尔曲线路径上的点拖动贝塞尔曲线

时间:2016-06-09 18:02:42

标签: uibezierpath bezier nsbezierpath

Sample image for the requirement我使用UIBezier路径代码绘制了闭合路径bezier曲线。我能够找到屏幕上的触摸点是否在闭合的贝塞尔曲线路径边界或其外部。 要求: - 我需要拖动用户触摸闭合路径贝塞尔曲线边界的点,并使闭合路径贝塞尔曲线延伸。

参见: - 以下问题与我的相同,但我无法从中找到解决方案。 https://math.stackexchange.com/questions/53819/changing-a-bezier-curve-by-dragging-a-point-on-the-curve-itself-rather-than-a-co

如果我能够获得Objective C代码或算法来执行上述功能,那将是一个很大的帮助。

嗨方,我已在我的帖子中发布了图片,说明了要求。 目前我只有点A和点B来自用户触摸和移动手指。 我需要计算点C和D并删除路径CD,使其看起来像原始曲线只是在用户手指移动方向上展开。

注意: - 当我得到一个闭合的曲线时,我会做这一切。如果没有关闭,用户就可以绘制无法实现的自由手。目前使用四线曲线满足我的要求。

任何帮助都会很棒。

1 个答案:

答案 0 :(得分:0)

假设你有一个二次Bezier曲线C(t),你想要拖动的A点在参数t0,那么我们有

 A=C(t0)=(1-t0)^2*P0+2t0(1-t0)*P1+t0^2*P2        (1)

现在,您将A点拖到B,所以我们有

 B=D(t0)=(1-t0)^2*Q0+2t0(1-t0)*Q1+t0^2*Q2        (2)

由于我们希望C(t)和D(t)共享相同的终点,因此我们得到P0 = Q0和P2 = Q2。然后,从等式(1)和(2),我们有

 B-A = 2t0(1-t0)(Q1-P1), or
 Q1 = (B-A)/(2t0(1-t0)) + P1

同样,如果你有一个三次贝塞尔曲线,我们将有

 A=C(t0)=(1-t0)^3*P0+3t0(1-t0)^2*P1+3t0^2(1-t0)*P2+t0^3*P3        (3)
 B=D(t0)=(1-t0)^3*Q0+3t0(1-t0)^2*Q1+3t0^2(1-t0)*Q2+t0^3*Q3        (4)

再次,结合(3)和(4)并保持相同的终点P0 = Q0和P3 = Q3将导致

  B-A = 3t0(1-t0)^2*(Q1-P1)+3t0^2(1-t0)*(Q2-P2),

我们有

  Q1= w(B-A)/(3t0(1-t0)^2) + P1, and
  Q2= (1-w)(B-A)/(3t0^2(1-t0)) + P2

其中w只是[0,1]之间的加权值。

正如您所看到的,对于三次贝塞尔曲线,您实际上有无限的移动P1和P2的解决方案,以便将点C(t0)从A点移动到B点。您可以选择仅移动P1或P2 (通过将w设置为0.0或1.0)或移动它们(通过将w设置为介于0.0和1.0之间的任何值)。更复杂的算法将通过最小化C(t)和D(t)之间的积分差来决定w的值,但我想我们不需要去那里。

以上只是对您帖子中链接中提到的“解决方案1”的更详细说明。我建议你采用这种方法(与解决方案2相比)。如果你有二次或三次贝塞尔曲线,找到与C(t0)点相关的参数t0只是找到2或3次多项式的根,这应该不难。