可可:两点之间的“随机”线?

时间:2012-03-09 21:21:07

标签: objective-c macos cocoa noise nsbezierpath

在我的Cocoa业余爱好项目中(在OSX上),我看到了一些观点。像这样:

NSPoint pt1 = NSMakePoint(20,100);
NSPoint pt2 = NSMakePoint(100,30);

我想在这两点之间创建一条曲折线(从不穿过它自己)。当然,这些要点可能会有所不同。我熟悉NSBezierPath,但我不是图形高手。

这有两种变化。给定NSBezierPath *p ...并设置[p moveToPoint:pt1]

  1. 使用[p lineToPoint:ptx]创建一条锯齿状的曲线和
  2. 使用[p curveToPoint:ptx controlPoint1:cpt1 controlPoint2:cpt2]使用平滑的曲线。
  3. 第二种情况似乎更难,因为必须计算合理的控制点。

    最后,我希望能够调整线条蜿蜒的数量。如果我将int numOfIntermediatePoints之类的变量设置为1,那么pt1pt2之间会有一条平滑的曲线。如果我将numberOfIntermediatePoints设置为10,那么该行中将会有更多的移动。我不希望最后一个中间点离最后一点很远(在行尾留下一个很大的变化)。

    我已经研究过使用Perlin噪音,但似乎很难引导该线朝向它的终点。似乎计算一个NSPoint项数组(可能是一组控制点,对于情况二)然后遍历它们以创建该行是有意义的。

    最好的方法是什么?


    更新

    根据Tommy的建议,我将Raymond Hill's Javascript-Voronoi库移植到Obj-C。您可以在此处找到它:https://github.com/ccheaton/objcvoronoi


    另一次更新

    还有一个更新 - 我使用了Dijkstra的算法,并发现它对于我想要实现的目标而言是过度的。我最终实现了它的简化变体,允许我为随机线指定引导节点。在此图像中,行开头位于中间左侧,行结束位于中间右侧,导向点位于(xMax * 0.33,0)和(xMax * 0.66,yMax)。

    Example of pathfinding


    最终更新

    为了减少锯齿状,我添加了一个可选的松弛算法。现在表现不是很好,但这与我想到的用途无关。

    Relaxation algorithm applied to cell sites

1 个答案:

答案 0 :(得分:3)

有许多方法让人想起。

就代码而言,您可以直接从互联网上取下,您可以拉下随机迷宫生成器和迷宫求解器,然后根据需要生成带入口和出口点的迷宫,并采取解决方案。

随着时间的推移,你可以尝试一种递归的方法 - 从头到尾以直线开始,然后是你的每条直线:

  • 想象一下,你要把它划分为两个,将它分成中心点并将其移动到某个地方;所以...
    • 计算出正常的行
    • 弄清楚在你的线与预先存在的线重叠之前你可以移动假想中心切点的距离是多少(最简单的方法就是二元搜索,我认为,而不是任何分析)
    • 如果两个极端太靠近,那么返回
    • 否则在两个极端之间选择一个随机位置,打破线并递归

对于其他有趣的想法,你在起点和终点之间抛出一堆随机点,计算Voronoi图,然后从起始点走到(i)边界的任何地方; (ii)根据到终点边界的最短路径沿着单元边界(例如,使用Dijkstra算法);然后(iii)到终点。然后,您可以浏览由(ii)添加的每个顶点到顶点的链接,并找到从潜在集中消除所有当前选定链接的最短路径,并重复几次以使路径更有趣。

从大致相同的思想流派中,在点之间投掷一堆随机障碍并运行A *式探路者可能会产生一些有趣的东西。