分割贝塞尔曲线

时间:2011-12-03 17:25:45

标签: math ios4 split bezier

我正在开发一款适用于iPhone的游戏,它会在您移动角色后创建一条路径(移动类似于蛇但在转向方面是弯曲的)。我现在这样做的方法就是将玩家所有的顶点保持在一个数组中,然后在每一帧中每一个都画一个圆圈。

我想转而使用贝塞尔曲线。我已经完成了很多关于它们的阅读,并且我对它们理解得很好,但我对数学并不是很好。我已经明白我应该使用DeCasteljau的算法将曲线分成特定的t但是我还没有找到使用哪个公式以及如何在代码中实现它。 / p>

所以我目前拥有的是t = 1时曲线的所有控制点。现在我只想获得t <1的所有控制点。有人可以给我一个易于理解的数学公式或者这个实现(最好是python或objective-c)。也许甚至还有一个可以在iphone sdk中用来分割曲线的物体?

3 个答案:

答案 0 :(得分:15)

我设法让它工作,实际上非常简单的数学。只需计算贝塞尔曲线的所有切线,就可以获得积分。

这里有一些python:

def sliceBezier(points, t):
    x1, y1 = points[0]
    x2, y2 = points[1]
    x3, y3 = points[2]
    x4, y4 = points[3]

    x12 = (x2-x1)*t+x1
    y12 = (y2-y1)*t+y1

    x23 = (x3-x2)*t+x2
    y23 = (y3-y2)*t+y2

    x34 = (x4-x3)*t+x3
    y34 = (y4-y3)*t+y3

    x123 = (x23-x12)*t+x12
    y123 = (y23-y12)*t+y12

    x234 = (x34-x23)*t+x23
    y234 = (y34-y23)*t+y23

    x1234 = (x234-x123)*t+x123
    y1234 = (y234-y123)*t+y123

    return [(x1, y1), (x12, y12), (x123, y123), (x1234, y1234)]

致电:

sliceBezier([(point1_x, point1_y),(controlpoint1_x, controlpoint1_y),(controlpoint2_x, controlpoint2_y),(point2_x, point2_y)], 0.23);

答案 1 :(得分:3)

如果你有一个现代浏览器take a look here,我实现了类似的东西。它在javascript中实现,并且还支持更高阶的beziers。

答案 2 :(得分:0)

这是使用Apple的SIMD API的解决方案。简洁明了,可返回两条细分曲线。

void SplitBezier(float t,
                 simd_float2 cv[4],
                 simd_float2 a[4],
                 simd_float2 b[4]) {

  a[0] = cv[0];
  b[3] = cv[3];

  a[1] = simd_mix(cv[0], cv[1], t);
  b[2] = simd_mix(cv[2], cv[3], t);

  auto b12 = simd_mix(cv[1], cv[2], t);

  a[2] = simd_mix(a[1], b12, t);
  b[1] = simd_mix(b12, b[2], t);

  a[3] = b[0] = simd_mix(a[2], b[1], t);

}