圈到圈段碰撞

时间:2010-11-19 15:17:55

标签: algorithm collision-detection trigonometry geometry game-physics

我正在努力找到一个坚如磐石的解决方案来检测圆圈和圆弧段之间的碰撞。想象一下游戏敌人的视野锥,圆圈代表感兴趣的物体。

底部的图表是我试图找出一些可能的案例,但我确信还有更多。

我理解如何快速排除极端情况,我丢弃任何不与整个圆相撞的目标,以及主圆的中心在目标圆内的任何情况都自动为真(图中的E)

我很难找到一个检查其余案例的好方法。我已经尝试比较圆心和段外线的终点之间的距离,并且我已经尝试从主圆的中心计算目标圆的中心角度并确定它是否在段内,但似乎都没有抓住所有案例。

具体来说,如果目标圆靠近中心但没有接触到它(下面的E和B之间的某个地方),或者如果该段比目标圆窄(以便中心位于该段内),它似乎变得很时髦但两边都在它之外。)

有可靠的方法吗?

额外信息:细分由位置P,方向O(其大小为圆半径)和视图大小S来描述。

我迄今为止最成功的尝试涉及确定向量ca1和ca2的角度,并检查它们中的任何一个是否位于向量a1和a2的角度之间。这适用于如上所述的某些情况,但不适用于目标圆大于分段的情况。

编辑2 在实施了下面的最佳建议之后,仍然存在误报,我不确定如何最好地消除。请参见下面的粉色图表。右下方的圆圈报告为与段相撞,因为它的边界与半圆和主圆重叠。

collision types current solution

false positive edge case


最终修改

在发现另一个边缘案例(第4张图片)之后,我已经确定了一种方法,它结合了下面的两个顶级答案,似乎涵盖了所有基础。我会在这里为了跟随者而描述它。

首先排除任何未通过快速圆圈测试的内容。

然后测试圆与段的两个外线之间的碰撞。如果它接触到,则返回true。

最后,使用圆心和两条外线(如下面的Gareth所述)进行几次点到半空间测试。如果它通过了它们的两个,否则返回false。

2 个答案:

答案 0 :(得分:5)

一个。检查它是否与整个cirlce相交 B.检查它是否与直线段相交 C.如果没有,检查圆心之间的角度是否在段的角度范围内(点积对此有利)。

交叉点需要A && (B || C)

答案 1 :(得分:3)

圆弧段(中心角小于180°)是三个数字的交点:圆形和两个半平面:

alt text

因此,只有当图形与所有这三个图形相交时,图形才会与圆弧段相交。 [仅当时才是,而时不是;见下文。]

圆/圆交点很容易(比较它们的中心与它们的半径之和的距离)。

对于圆/半平面交点,表示 p n k 形式的半平面(其中 p 是要测试的点, n 是与定义半平面的线垂直的单位向量, k 是常量)。如果 x · n ,则中心 x 和半径 r 的圆与半平面相交k + r

(如果您需要处理中心角大于180°的圆弧段,请将其分成两段,中心角小于180°。如果我正确理解您的问题描述,则无需执行此操作,因为你的视野总是小于180°,但值得一提。)

编辑添加:如beeglebug所指出的,圆圈可以与所有三个数字相交而不会相交。哎呀。但我相信只有当圆圈位于线段中心后面时才会发生这种情况,如下图所示,在这种情况下,我们可以对凸起的数字应用分离轴测试

A circle failing to intersect a circular segment, with an axis shown separating them

分离轴定理说,如果存在一条线,使得一个图形完全落在线的一侧,而另一个图形落在另一侧,则两个凸形图不能相交。

如果在这种情况下存在任何分离轴,则垂直于圆心和分段中心之间的直线的轴是分离轴(如图所示)。

让段的中心位于原点,让圆具有中心 x 和半径 r ,让两个半平面具有(向外)法线 n 1 n 2 。如果

,该圈位于该段的“后面”
  

x · n 1 > 0和 x · n 2 > 0

,如果

,轴将其与段分开
  

| <强> X | &GT; - [R

A circle failing to intersect a circular segment, with an axis shown separating them, with points, normals and radius marked