凹多边形之间碰撞检测的算法

时间:2013-12-11 21:05:10

标签: collision-detection

凹多边形之间是否有任何良好的检测算法?我很感激任何帮助,因为到目前为止我只发现了凸多边形之间的检测算法。

2 个答案:

答案 0 :(得分:8)

您可能会发现this纸张很有趣。

答案 1 :(得分:3)

这已经过时了,但仍然具有相关性,而且这个问题似乎没有很多答案,所以这里有:

对于整体形状不变的多边形(可以旋转和缩放,但顶点之间的关系可能不会改变),有一些方法可以预处理顶点数据,以实现一系列和/或一系列测试。用于测试另一个多边形是否与其碰撞的多边形。

我正在编写此算法的过程中,因此我将为您提供背后的理论,而不是现成的理论:

传说:&&意味着AND,||是指OR。

步骤1a:

通过多边形的线条并测试每条线对着它的所有其他点,我们将所有其他点都在线上或“内部”的线分开。这条线的一面。

这些收集的行在碰撞检查公式中形成一个新节点,它们被认为是相互关联的逻辑AND检查。

步骤1b:

将每个孤立的顶点组分离到它们自己的集合中,并将它们分别提供给下一步:这些岛被认为是彼此相关的逻辑AND。

步骤1c:

如果在步骤1a中收集了任何行,并且由于进入步骤3a / 3b,我们一次收集多行,重置步骤3a / 3b中设置的任何变量,然后再回到1a。

步骤2a:

通过多边形的线条并测试每条线对着它的所有其他点,我们将所有其他点都在“外线”上的线分开。多边形的一侧(或者更具体地说,所有这些都在线的非碰撞侧)。

这些收集的行在碰撞检查公式中形成一个新节点,它们被认为是相互关联的逻辑OR检查。

步骤2b:

将每个孤立的顶点组分隔为它们自己的集合,并将它们分别提供给后续步骤。这些岛屿被认为是彼此相关的逻辑或。

步骤2c:

如果在步骤2a中收集了任何行,则重置步骤3a / 3b中设置的所有变量,然后再回到1a。

步骤3a:

进入这个阶段意味着没有剩下的行所有顶点都落在其中一侧,这意味着我们需要更积极地收集这些行:

提高步骤1a和2a中要收集的连续行数。这意味着代替所有顶点落在一条线的一侧,它们必须落在至少一条收集线的一侧(1a内侧和2a外侧)。一旦收集到任何行,这将重置为1。

步骤3b:

如果要收集的连续行数超过形状中的行数,请将数字重置为2并允许收集非连续行(到达此处也是一个很好的迹象,表明您的网格有点复杂而且您可能想要考虑减少一点,但是到3a是没什么大不了的,因为一个简单的星形需要输入它才能解决。)

使用生成的节点进行碰撞测试时,只需将对象的形状(点/线/圆)提供给逐个测试经过处理的网格进入节点。

对于要进行碰撞测试的两个多边形,其中只有一个必须像这样处理。

为示例多边形创建公式:

1)将示例多边形输入步骤1a:

Example polygon after step 1a

图片中的红线是所有其他顶点都落在其中的所有线条,因此形状必须位于所有其中,以使形状能够与多边形碰撞。

在1b之后,多边形将被分成两个(A和B)。

2)将A和B喂入步骤2a:

Example polygon after step 2a

图片中的绿线是所有其他顶点都在其外的所有线条,因此如果形状位于其中一个内部,则会发生碰撞。

在2b之后,两个孤立的多边形A和B将进一步分为C,D,E和F.

3)将C,D,E和F加入步骤1a:

Example polygon after step 1a

多边形C将丢失一条线(让我们调用新的形状G),在步骤1b之后D将被分成两个(H和I),而多边形E和F没有剩余线要收集。

4)将G,H和I喂入步骤2a:

Example polygon after step 2b

在步骤2c之后,多边形G将被分成两个(J和K),H将丢失2行(称为新形状L),我将没有剩余的线来收集。

5)将J,K和L喂入步骤1a:

Example polygon after step 1a

在此之后,只需重复3次步骤即可收集所有行。

原始多边形的最终公式变为: Final formula on one line and with phases marked down 更直观的表示:Final formula with visual representation

这里是原始多边形,其中的行标记为:Polygon with lines marked

使用这种方法,凹面多边形与测试碰撞的速度相同甚至更快,而不是将它们分解为凸多边形(如果两个顶点具有相同数量的顶点,则最坏情况是同一时间,最佳情况可以切割测试从步骤1开始的所有线和从步骤2开始的一条线,如果在其他地方发生碰撞,则切断对形状的任何更复杂的波形线的测试。

此算法的局限性至少如下:

1)如果动画多边形的顶点,则上述公式不再适用,必须重新制作。这对于少量不太复杂的多边形来说不是问题,因为上面的步骤并不是很复杂(需要(n - 2)^ 2的"这一点所在的那一行位于" ; - 在整个步骤中可以缓存和重复使用其结果的测试。)

2)不会自动处理多边形中的孔。也可以像上面那样处理孔,并且只应用以下规则:与原始多边形碰撞的形状也必须a)与孔的线相交或b)不与孔多边形碰撞以发生碰撞

3)我提出的关于如何打破多边形的规则没有针对任意复杂的多边形进行测试,可能还需要进一步的规则来处理它们。

4)你必须自己编写算法的代码,因为在我有一个可用的通用版本之前我无意发布,这可能需要一段时间。