检测两个矩形相交的算法?

时间:2020-03-06 14:32:40  来源:igfitidea点击:

我正在寻找一种算法来检测两个矩形是否相交(一个以任意角度相交,另一个仅以垂直/水平线相交)。

测试一个角是否在另一个ALMOST中是可行的。如果矩形形成十字形,则失败。

避免使用直线的斜率似乎是个好主意,因为直线的斜率需要特殊情况。

解决方案

如果我们使用的是Java,则Shape接口的所有实现都有一个采用矩形的相交方法。

好吧,蛮力方法是沿着水平矩形的边缘走,并检查沿该边缘的每个点,看它是否落在另一个矩形上或者在另一个矩形中。

数学答案是形成描述两个矩形的每个边缘的方程。现在,我们可以简单地找到矩形A的四条线中的任何一条是否与矩形B的任何线相交,这应该是一个简单的(快速)线性方程求解器。

-亚当

检查一个矩形中的任何线是否与另一矩形中的任何线相交。朴素的线段交点很容易编码。

如果需要更高的速度,则可以使用高级算法来处理线段交点(扫线)。参见http://en.wikipedia.org/wiki/Line_segment_intersection

我们可以找到成角度的矩形的每一侧与轴对齐的矩形的每一侧的交集。通过找到每条边所在的无穷线的等式(即v1 + t(v2-v1)和v'1 + t'(v'2-v'1)来确定),找到当这两个方程相等时,通过求解t来满足直线(如果它们是平行的,则可以进行测试),然后测试该点是否位于两个顶点之间的线段上,即0 <= t <= 1和0 <= t'<= 1.

但是,当一个矩形完全覆盖另一个矩形时,这并不适用。我们可以通过测试一个矩形的所有四个点是否都位于另一个矩形内来进行覆盖。

基本上看下图:

http://www.gamasutra.com/features/20000330/bobic_08.gif

如果两个框发生碰撞,则线A和B将重叠。

请注意,这必须同时在X和Y轴上进行,并且都需要重叠以使矩形发生碰撞。

gamasutra.com上有一篇很好的文章可以回答这个问题(图片来自该文章)。
我在5年前做过类似的算法,所以我必须找到我的代码段才能稍后在此处发布

修改:分离轴定理指出,如果存在分离轴,则两个凸形不重叠(即所示的投影不重叠的凸形)。因此,"存在分离轴" =>"无重叠"。这不是双向含义,因此我们不能得出相反的结论。

对于这个问题的3D版本,这就是我要做的事情:

将这两个矩形建模为等式P1和P2所描述的平面,然后写P1 = P2并从中得出相交线方程,如果平面平行(无相交)或者在同一平面中,则该相交线将不存在,在这种情况下,我们得到0 = 0。在这种情况下,我们将需要使用2D矩形相交算法。

然后,我将查看在两个矩形的平面中的那条线是否穿过两个矩形。如果是这样,则我们有2个矩形的交集,否则就没有(或者不应该,我可能会错过一个脑袋)。

为了确定一条线是否穿过同一平面中的一个矩形,我会找到该线和该矩形的边的2个交点(使用线方程对它们进行建模),然后确保该交点与in范围。

那是数学上的描述,不幸的是我没有上面的代码来做。

标准方法是进行分离轴测试(对此进行Google搜索)。

简而言之:

  • 如果可以找到将两个对象分开的线,则两个对象不相交。例如对象/对象的所有点都在直线的不同侧。

有趣的是,仅检查两个矩形的所有边缘就足够了。如果矩形不重叠,则边缘之一将成为分隔轴。

在2D中,我们可以不使用坡度来执行此操作。一条边简单地定义为两个顶点之间的差异,例如

edge = v(n) - v(n-1)

我们可以通过旋转90度来获得垂直于此的垂直度。在2D中,这很容易做到:

rotated.x = -unrotated.y
  rotated.y =  unrotated.x

因此,不涉及三角函数或者斜率。也不需要将向量标准化为单位长度。

如果要测试点是否在直线的一侧或者另一侧,则可以使用点积。标牌会告诉我们我们在哪一边:

// rotated: your rotated edge
  // v(n-1) any point from the edge.
  // testpoint: the point you want to find out which side it's on.

  side = sign (rotated.x * (testpoint.x - v(n-1).x) + 
               rotated.y * (testpoint.y - v(n-1).y);

现在,针对矩形B的边缘测试矩形A的所有点,反之亦然。如果找到分离的边缘,则对象不相交(假设B中的所有其他点都在要测试的边缘的另一侧,请参见下图)。如果找不到分隔边,则两个矩形相交,或者另一个矩形中包含一个矩形。

该测试适用于所有凸多边形btw ..

修正:要确定分隔边缘,仅将一个矩形的所有点与另一个矩形的每个边缘进行对比测试是不够的。由于A中的所有点都在E的同一半平面中,因此候选边E(如下)将被标识为分离边。但是,它不是分离边,因为B的顶点Vb1和Vb2也在那个半平面内。如果不是这种情况,那只会是一个分离的边缘
http://www.iassess.com/collision.png

一种解决方案是使用一种称为"不适合多边形"的方法。从两个多边形计算出此多边形(从概念上讲,一个在另一个周围滑动),并根据给定的相对偏移量定义了多个多边形重叠的区域。有了该NFP之后,我们只需要对由两个多边形的相对偏移量给出的点进行包含性测试。此包含测试快速简便,但是我们必须首先创建NFP。

在网上搜索"不适合多边形",看看是否可以找到凸多边形的算法(如果我们有凹多边形,则算法会变得更加复杂)。如果找不到任何内容,请给我发送电子邮件,地址为:霍华德点J点可gmail点com