连续物理引擎的碰撞检测技术


10

我正在使用一个纯粹的连续物理引擎,因此我需要选择用于宽相和窄相碰撞检测的算法。“完全连续”表示我从不进行交叉测试,而是想找到方法在每次碰撞发生之前将其捕获,然后将其放入由TOI排序的“计划的碰撞”堆栈中。

宽相 我能想到的唯一连续的宽相方法是将每个物体围成一个圆圈,并测试每个圆圈是否会相互重叠。但是,这似乎效率极低,并且没有任何剔除。

我不知道对于今天的离散碰撞剔除方法(例如四叉树),可能存在什么连续的类似物。我应该如何防止不适当且毫无意义的广泛测试,例如分立引擎?我还希望能够看到超过1帧的碰撞。

狭窄阶段
我已经设法使狭窄的SAT适应连续检查而不是离散检查,但是我敢肯定,您可能遇到过的论文或网站中还有其他更好的算法。
您建议我使用哪种快速或准确的算法,每种算法的优点/缺点是什么?

最后说明:
我说的是技术而不是算法,因为我尚未决定如何存储可能是凹形,凸形,圆形甚至有孔的不同多边形。我计划根据算法的要求对此做出决定(例如,如果我选择将多边形分解为三角形或凸形的算法,我将以这种形式简单地存储多边形数据)。



很抱歉添加,但是为什么不使用Box2D?它已被移植到几乎每种语言。如果您不打算使用它,为什么不浏览它的源代码,以便可以看到它如何管理共谋?
德里克(Derek)

Answers:


2

我真的只是在这里提出想法。假设您(至少)拥有该current职位和next职位;每帧。

您将需要两个单独的主要阶段,然后是您的狭窄阶段:

  • 指出会发生碰撞的人。
  • 大致指出碰撞实际发生的位置(例如,宽相位/不准确的SAT)
  • 最后,您的狭窄阶段将改善第二个广泛阶段的结果。

初期广泛阶段

您可以针对初始广泛阶段研究空间哈希(使用nextposition而不是current)。这样可以将您的问题空间很好地划分为碰撞候选者组。

第二阶段

使用您描述的圆相交方法进行二值多重采样。换一种说法:

left = current
right = next
midpoint = (left + right) / 2
loop a desired amount of times tweaked to the accuracy you want:
  is a collision occuring at midpoint?
    right = midpoint
  else?
    left = midpoint
  midpoint = (left + right) / 2
pointOfCollision = midpoint

精度调整还可以考虑距离-我认为使用的“长度平方” next - current将获得像素完美的结果。

窄相

使用PMask之类的工具进行二进制多采样-逻辑与上面完全相同;只是使用不同的碰撞程序。

最后

您将能够从中计算出相交时间pointOfCollisioncurrent以及当前speed和的相交时间acceleration(假设您有一个合理的积分器)。


因此,对于次级广义相位检测,您是否建议我得到圆的行进路径的中点,并测试它是否在要测试的圆内?我当时想我可以简单地创建一个方程,该方程给出两个圆随着时间的推移彼此之间的距离,并查看该距离是否随时等于
Griffin

另外,Pmask到底能做什么?该网站并没有真正解释= /。
格里芬

@Griffin,您的第一个评论可能有用-看看是否可以解决。我基本上是在碰撞空间上进行二进制搜索... PMask非常聪明。看到一个无符号的64-int像素为8x8像素网格(开/关)-一个简单的AND(二进制)确定是否发生冲突(非零);您需要先进行一些巧妙的移位,但这就是这个主意。阅读源代码以获取更多信息;在这里很难解释(或者说我的解释会很烂)-您确实需要参考源代码。
乔纳森·迪金森

1

好吧,我看过您已经更新了您的问题,以便更加具体。我会尽力帮助您。

对于您的第一次广泛阶段检查,我强烈建议您使用空间哈希

本质上,您将屏幕划分为相等大小的网格。然后,如果对象位于网格内,则将其添加到一维哈希表的“存储桶”中。

那是您的第一笔检查。如果对象不在同一存储桶中,则它们将不可能相交。

继续进行操作,现在您有了一个包含对象(可能)的存储桶列表。您可以通过以下任一方法在此处进行另一大阶段检查:

A.)将此存储桶分为其他4个存储桶,并检查生成的1D哈希表。如果它们不在同一个存储桶中,则不会发生冲突。

要么:

B.)做一次简单的距离检查,并牢记物体的宽度和/或高度,以确保准确性。

但是,当您可能发生碰撞时该怎么办?

然后,我将根据此内容提出一些建议。它本质上是多边形碰撞(对于复杂形状)或矩形/圆形(对于不太复杂的形状)之间的混合。

另外,如果您真的想“在碰撞发生之前将其捕获并存储”,那么您始终可以执行以下操作:

如果两个对象在同一存储桶中,则它们可能会碰撞。

此外,物体是否足够近以至于可能很快碰撞?(考虑速度,物体大小和距离)

如果两者的答案都是肯定的,则继续进行存储,以便以后进行交叉测试。


旧答案

好吧,不幸的是,我忘记了我的《所有碰撞类型及其用途》手册。:)

但是,即使这是一个极其广泛的问题,我也会帮助您入门。

有关于这样的一个很好的(回答)的问题在这里

以及在这里制作N和N +的人们的一篇文章。

更不用说,您拥有出色的后备Per-pixel Collision

我真诚地怀疑,任何人都会有每种碰撞的清单,但是这应该有助于您入门。

但是,我应该提到您需要(并将最终使用)的碰撞类型在很大程度上取决于您正在创建的游戏的类型。这就是为什么您找到教程的原因-大多数人都认为您对所需内容有所了解,因此他们会在特定领域提供帮助。我意识到我的大多数链接都是关于特定主题的教程,但是我认为教程将诚实地为您提供更多帮助。列表是一回事,但是如果您自己阅读每个项目要点,则可以做出更有根据的决定,这可能更适合您的需求。


忘了添加我基于碰撞的方法(使用船体设计的Per-Pixel)原谅存档,原始站点已移至天堂。web.archive.org/web/20090126230334/http://www.ziggyware.com/...
electroflame
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.