Math / Algorithm / JS:给定每个矩形的TopLeft(x0,y0)和Bottom-Right(x1,y1),如何确定2个以上的矩形是否相交

时间:2011-11-03 04:32:13

标签: php javascript algorithm math intersection

我遇到了完成申请所需的数学问题,所以我正在寻求帮助。

给出2个(或更多,但基本上为2个)矩形,每个矩形有2个已知点: 左上角(x1,y1) 右下角(x2,y2) (如果需要解决问题,我可以找到这些信息的长度。)

TL(x1, y1)
   +-----------------+
   |                 |
   |                 |       TL(x3, y3)
   |                 |            +---------------------------+
   +-----------------+            |                           |
               BR(x2, y2)         +---------------------------+
                                                         BR(x4, y4)

无论如何确定他们是否有交叉,在区域,我的意思是,如果这个矩形的任何部分放在另一个的任何部分上?

我已经搜索并找到了一点帮助,但它没有解决问题:

  

有两种情况,两个矩形不会相交:

     
      
  • 一个矩形的左边缘位于另一个矩形的右边缘的右侧,意味着第一个矩形的左边缘完全位于第二个矩形的右侧,没有交叉点。

  •   
  • 一个矩形的右边缘位于另一个矩形左边缘的左侧,意味着第一个矩形的右边缘完全位于第二个矩形的左侧,没有交叉点。

  •   
  • 一个矩形的上边缘位于另一个矩形的下边缘,意味着第一个矩形完全位于第二个下方,没有交叉点。

  •   
  • 一个矩形的下边缘位于另一个矩形的上边缘上方,意味着第一个矩形完全位于第二个上方,没有交叉点。

  •   

所以我试图扭转条件,即如果上面的4个没有发生,矩形 可能 相交。但我仍然可以找到2个矩形不满足任何条件但仍然不相交的条件(如上图)。

任何帮助都非常感谢,请告诉我这样做的方法或算法或代码(仅限JS和PHP)。

非常感谢!

[X]

2 个答案:

答案 0 :(得分:5)

任意数量的交叉检测(“重叠”)的算法 矩形可以如下工作。使用两种数据结构。

  • 矩形左右边缘的x坐标的排序列表S.
  • 矩形的y坐标(底部/顶部)给出的interval tree T间隔。

算法扫过x坐标的排序列表S:

  1. 如果当前的x坐标是矩形R的左边缘 将R的y坐标[y1,y2]与区间树T进行比较。 如果找到重叠,则算法停止并报告OVERLAP。如果 在树T中没有重叠,那么区间[y1,y2]是 插入树中。

  2. 如果当前的x坐标是矩形R的右边缘 从区间树T中删除其y-区间[y1,y2]。

  3. 如果完全处理了排序列表S,则没有重叠。该算法停止并报告NO-OVERLAP。

  4. N个矩形的时间复杂度为O(N * log(N)) 因为每个2 * N. x坐标在区间树中搜索N个区间。 对于辅助数据结构S和T,空间复杂度为O(N)。

答案 1 :(得分:0)

这是我对问题的两分钱。如果可以改进,请告诉我。我自己做的例子似乎适用于这段代码,但是如果你能给我一些例子坐标让这个失败,我仍然想解决这个问题:)

 <?php

//declare the points for your rectangles
//'UL' means upper left points, and 'LR' means the lower right points
$rectangle_array = array(
    $R1 = array("UL" => array("x" => 10, "y" => 20), "LR" => array("x" => 22, "y" => 5)),
    $R2 = array("UL" => array("x" => 32, "y" => 44), "LR" => array("x" => 65, "y" => 20)),
    $R3 = array("UL" => array("x" => 20, "y" => 16), "LR" => array("x" => 25, "y" => 10))
);


if (rectIntersect($rectangle_array)) {
    echo "THEY INTERSECT";
} else {
    echo "NO INTERSECTION";
}

function rectIntersect($rectangles) {
    $num_rectangles = count($rectangles);
    for ($i = 0; $i < $num_rectangles; $i++) {
        //for each rectangle, compare points to every following rectangle
        $R1 = $rectangles[$i];
        for ($k = $i; $k < ($num_rectangles - $i); $k++) {
            $R2 = $rectangles[$k + 1];
            if ($R1['LR']['x'] > $R2['UL']['x'] && $R1['UL']['x'] < $R2['LR']['x']) {
                //rectangles cross on x-axis
                if (($R1['LR']['y'] < $R2['UL']['y'] && $R1['UR']['y'] < $R2['LR']['y']) ||
                        ($R1['UL']['y'] > $R2['LR']['y'] && $R1['LR']['y'] < $R2['UL']['y'])) {
                    //rectangles intersect
                    return true;
                }
            }
        }
    }
    return false;
}

?>