【问题标题】:Algorithms for collision detection between concave polygons凹多边形间碰撞检测算法
【发布时间】:2021-07-14 01:32:21
【问题描述】:

凹多边形之间有什么好的检测算法吗?到目前为止,我只找到了用于检测凸多边形之间的算法,我将不胜感激。

【问题讨论】:

  • 你有没有看那个问题的标题?这是关于凸多边形的,我的问题是关于凹多边形的。
  • 我也是来寻找答案的,但我的解决方案是将凹多边形分解为凸多边形。我们可以用吃豆人做到这一点,但新月呢?所以我要去下面的答案。

标签: collision-detection


【解决方案1】:

This 2004 年的论文探讨了一种有效的二维多边形碰撞检测算法,无论是凹面还是凸面。

如果链接失效,这里有一些作者/引文信息:

Juan José Jiménez、Rafael J. Segura、Francisco R. Feito
信息部门。 E.P.S.J.哈恩大学

WSCG 杂志,第 12 卷,第 1-3 期,ISSN 1213-6972

【讨论】:

    【解决方案2】:

    这是旧的,但仍然相关,对于这个问题似乎没有很多答案,所以这里是:

    对于整体形状不变的多边形(可以旋转和缩放,但顶点之间的关系可能不变),有一些方法可以对顶点数据进行预处理,以实现对多边形来测试另一个多边形是否与它发生碰撞。

    我正在编写这个算法,所以我会为你提供它背后的理论,而不是现成的:


    图例:&& 表示 AND,||表示或。

    步骤 1a:

    遍历多边形的线并将每条线与它的所有其他点进行测试,我们将所有其他点在线上或线的“内侧”一侧的线分开。

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

    步骤 1b:

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

    步骤 1c:

    如果在第 1a 步期间收集了任何行,并且由于进入第 3a/3b 步而我们一次收集多行,请重置在第 3a/3b 步中设置的所有变量并直接返回到 1a。

    步骤 2a:

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

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

    步骤 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),D 将在步骤 1b 之后被孤立成两个(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) 你必须自己编写算法的代码,因为在我有一个可以工作的通用版本之前,我不打算发布,这可能需要一段时间。

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 2022-01-22
      • 2013-03-09
      • 1970-01-01
      相关资源
      最近更新 更多