【问题标题】:Math/ Algorithm/ JS: How to determine if 2+ rectangles intersect, given the TopLeft(x0, y0) and Bottom-Right(x1, y1) of each rectangle数学/算法/ JS:如何确定 2+ 个矩形是否相交,给定每个矩形的 TopLeft(x0, y0) 和 Bottom-Right(x1, y1)
【发布时间】:2011-12-20 21:01:01
【问题描述】:

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

给定 2 个(或更多,但基本上是 2 个)矩形,每个矩形有 2 个已知点:Top-left(x1, y1)Bottom-right(x2, y2)(如果需要解决问题,我可以通过这些信息找到长度)。

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

有没有办法确定它们是否有交集,在面积上,我的意思是,这个矩形的任何部分是否位于另一个矩形的任何部分上?

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

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

  • 一个矩形的左边缘在另一个矩形的右边缘的右侧,表示第一个矩形完全放在第二个矩形的右侧,没有交集。

  • 一个矩形的右边缘在另一个矩形的左边缘的左侧,意味着第一个矩形完全放在第二个矩形的左侧,没有交集。

  • 一个矩形的上边缘在另一个矩形的下边缘之下,表示第一个矩形完全位于第二个矩形之下,没有相交。

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

所以我试图颠倒条件,即如果上述 4 个不发生,矩形可能相交。但是我仍然可以找到两个矩形不满足任何条件并且仍然不相交的条件(如上图)。

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

非常感谢!

[x]

【问题讨论】:

  • 图表满足条件2。
  • 这看起来正是您所需要的:stackoverflow.com/questions/115426/…
  • @IgnacioVazquez-Abrams:谢谢伙计,现在我注意到了。
  • @nickb:我读过那篇文章,但真的不知道它是关于什么的>。
  • @nnnnnn:我的错,非常感谢你,现在我知道我可以使用该理论应用于我的代码。再次感谢你。 [x]

标签: php javascript algorithm math intersection


【解决方案1】:

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

 <?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;
}

?>

【讨论】:

  • 我建议您重命名变量以更好地指示哪个点属于哪个矩形的哪个角?例如,$r1TL(矩形 1 左上角)、$r1BR、$r2TL、$r2BR。我知道问题使用了 $x1 等,但这很令人困惑。
【解决方案2】:

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 2015-03-05
    • 2014-08-08
    相关资源
    最近更新 更多