无限期地随意移动物体而不会发生碰撞

时间:2014-04-16 06:26:49

标签: algorithm collision-detection path-finding

我有一个应用程序,我需要以随机方式在屏幕上移动大量对象,并且它们不能相互碰撞。我正在寻找一种算法,它允许我生成不会产生冲突的路径,并且可以无限期地继续(即:对象不断移动,直到用户驱动的事件将它们从程序中移除)。

我不是游戏程序员,但我认为这看起来像一个人工智能问题,你们可能会闭着眼睛解决它。从我读过的内容来看,A *似乎是推荐的“基本理念”,但我并不想在没有确认的情况下投入大量时间。

任何人都可以对某种方法有所了解吗?反重力运动可能吗?

  1. 如果重要的话,这将在iOS上实现
  2. 需要在每个路径的末尾生成新路径
  3. 没有可见的'网格'。在2D空间中移动是完全免费的
  4. 物体是在屏幕上走动直到它们被杀死的昆虫

5 个答案:

答案 0 :(得分:27)

A*是一种算法,用于找到开始和目标配置之间的最短路径(根据您定义为短的任何内容:常见的是例如欧几里德距离,成本或时间,角距...)。你的昆虫似乎没有特定的目标,甚至不需要最短的路径。我肯定不会去A*。 (顺便说一下,既然你有一个动态的环境,D*本来就是个主意 - 它仍然意味着找到从A到B的路径。)

我会按如下方式解决问题:

随机路径并跟随它们

对于随机路径,我看到两种方法。第一个是简单的随机游走(click here to see a nice 2D animation with explanations),它可能会受到抖动的影响并且看起来不太好。第二个需要更详细的解释。

对于每只昆虫,在它们周围产生四个随机点,可能从正弦曲线开始。使用spline interpolation在这些点之间生成平滑的曲线。注意C1(2D)或C2(3D)continuity。 (建议:Hermite splines) 使用Catmull-Rom splines,您可以在沿着曲线移动时找到您的配置。

可以找到类似方法的应用in this blog post about procedural racetracks,在计算机动画课程的these old slides (pdf)中也可以找到更技术性(但仍然不太技术性)的解释。

当昆虫开始移动时,它可以在第二点和第三点之间不断移动,当你总是移除第一点并在昆虫到达第三点时附加一个新点,从而使其成为第二点。

If third point is reached
    Remove first
    Append new point
    Recalculate spline
End if

对于更平滑的曲线,总共添加更多的点并在中间的某处移动,原则保持不变。 (我个人在固定环境中只使用它,但它也应该在动态环境中使用。)

如果您的随机点生成良好(也许您可以使用类似于上述链接博客文章中提供的方法,或者查看PCG Wiki上的算法),这可以导致顺利屏幕上的路径。

避免其他昆虫

为了避免其他昆虫,我想到了三种不同的方法。

  • Bug算法
  • Braitenberg车辆
  • 潜在领域的应用

对于潜在字段,我建议您阅读this paper about dynamic motion planning (pdf)。它来自机器人技术,但也很容易应用于你的问题。您可以使用机器人下一个样条点作为目标,并将其速度设置为0以应用此方法。但是,对于你的简单游戏来说,这可能有点太多了。

可以找到关于Braitenberg车辆的讨论here (pdf)。最初的想法更多的是一种技术方法(取决于你的电机如何与光接收器耦合,朝向或远离光源驱动),并且经常用于展示我们如何将恐惧和吸引等情感概念应用于其他物体。 “恐惧”行为也是一种用于机器人避障的方法。

第三种也许是最简单的方法是bug algorithms (pdf)。我总是遇到边界跟随问题,这有点棘手。但是为了避免另一种昆虫,这些算法 - 无论你使用哪种算法(我建议使用Bug 1或Tangent Bug) - 应该可以做到这一点。它们非常简单:朝着你的目标前进(在这个带有catmull-rom样条的应用程序中)直到你前面有一个障碍物。如果障碍物接近,将昆虫的状态更改为“避障障碍”并运行您的错误算法。如果你给两个“碰撞”的昆虫提供相同的转弯方向,它们会自动绕过彼此并沿着它们的原始路径前进 作为变体,您可以让它们转动并从该点重新计算新的样条线。

结论

路径查找和随机路径生成是不同的事情。你必须尝试最适合你的昆虫的东西。 A *绝对是用于寻找最短路径,而不是用于创建随机路径并跟随它们。

答案 1 :(得分:5)

查看thisthis其中描述了一个自动播放马里奥游戏的人工智能程序。

所以在这个链接中,作者所做的是使用A * star算法来指导马里奥Get to the right border of the screen as fast as possible. Avoid being hurt.

所以这个想法是针对每个时间框架,他将有一个描述场景中其他对象的当前位置的环境以及每个动作(向上,向左,向右,什么也不做),他计算其成本函数和基于此做出了下一步运动的决定。

来源:http://www.quora.com/What-are-the-coolest-algorithms

答案 2 :(得分:5)

您无法提前计划无限期的轨迹!

我建议使用一种更简单的方法来预测下一次碰撞(知道物体的位置和速度可以让你知道它们是否会发生碰撞以及何时碰撞),并通过改变任何一个物体的速度或方向来解决它(反弹)在物体碰到之前)。

确保在您创建更早的碰撞时重做检查碰撞!

在你的情况下,真正的挑战是有效地预测众多物体之间的碰撞,先验的O(N²)任务。您将通过在游戏区域上叠加粗网格并仅查看相邻单元格中的对象来加速它。

还可以维护“可能在某些未来干扰”的对象列表(即考虑它们的距离和相对速度)并保持更新。检查一对可能离开列表相对容易;有效地检查需要输入列表的新对是不是。

答案 3 :(得分:3)

对于A *,即使不可见,也需要2D网格。如果我的想法正确,你可以做到以下几点。

实现路径寻找(例如A *),然后在屏幕上生成随机目标点并计算路径。一旦你的昆虫到达目的地,产生另一个目的地点/网格单元并继续直到昆虫死亡。

正如我所看到的那样,如果你在屏幕上有障碍物,昆虫应该四处走动,只会产生一定的意义,否则它就足以计算一条直线矢量路径并可能处理与其他昆虫/物体的碰撞。

  

注意:我实施了A*一次,之后我发现Lee's Algorithm   几乎一样,但更容易实现。

答案 4 :(得分:2)

考虑Hamiltonian cycle - 这个想法是一次访问网格上所有位置的路线(只有一次)。如果你提前构造了这个循环(即预先计算它),并且在它们之间有一些偏移设置你的昆虫,它们将永远不会发生碰撞,因为路径从不相交。

此外,对于奖励积分,哈密尔顿路径往往会徘徊,因为它是一个循环,你可以预测(并预先计算)进入无限期未来的路径。

您始终可以使用网格的节点作为样条曲线的结点来平滑移动,或者甚至将所有点从其严格的2d网格位置随机移位,直到您获得所需的运动。

来自维基媒体的汉密尔顿循环示例:

在旁注中,如果要生成这样的路径,请考虑构建一个遍历多个点的循环,然后仅以它们从不与现有边相交的方式移动点。在鼓励进入差距并相互远离的情况下,他们应该陷入一条漫长而永不交叉的道路。存储结果并用于循环。