簡體   English   中英

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

[英]Math/ Algorithm/ JS: How to determine if 2+ rectangles intersect, given the TopLeft(x0, y0) and Bottom-Right(x1, y1) of each rectangle

我遇到了完成我的申請所需的數學問題,所以我正在尋求幫助。

給出2個(或更多,但基本上為2個)矩形,每個矩形有2個已知點: 左上角(x1,y1)右下角(x2,y2) (我可以找到這些信息的長度,如果是需要解決問題)。

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

無論如何確定它們是否有交叉,在區域中,我的意思是,如果這個矩形的任何部分放在另一個的任何部分上?

我搜索並找到了一些幫助,但它沒有解決問題:

有兩種情況,兩個矩形不會相交:

  • 一個矩形的左邊緣位於另一個矩形的右邊緣的右側,意味着第一個矩形的左邊緣完全位於第二個矩形的右側,沒有交叉點。

  • 一個矩形的右邊緣位於另一個矩形的左邊緣的左側,意味着第一個矩形的右邊緣完全位於第二個矩形的左側,沒有交叉點。

  • 一個矩形的頂部邊緣位於另一個矩形的底部邊緣下方,意味着第一個矩形完全位於第二個矩形的下方,沒有交叉點。

  • 一個矩形的下邊緣位於另一個矩形的上邊緣上方,意味着第一個矩形完全位於第二個上方,沒有交叉點。

所以我試圖扭轉條件,即如果沒有發生上述4,則矩形可能會相交。 但我仍然可以找到2個矩形不滿足任何條件但仍然不相交的條件(如上圖)。

任何幫助都非常感謝,請告訴我這樣做的方法或算法或代碼(僅限JS和PHP)。

非常感謝!

[X]

用於任何數量的矩形的交叉檢測(“重疊”)的算法可以如下工作。 使用兩種數據結構。

  • 矩形的左右邊緣的x坐標的排序列表S.
  • 由矩形的y坐標(底部/頂部)給出的間隔的間隔樹 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。

N個矩形的時間復雜度是O(N * log(N)),因為對於每個2 * N×坐標,在區間樹中執行N個區間的搜索。 輔助數據結構S和T的空間復雜度為O(N)。

這是我對這個問題的兩分錢。 如果可以改進,請告訴我。 我自己做的例子似乎適用於這段代碼,但是如果你能給我示例坐標使這個失敗,我仍然想解決這個問題:)

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

?>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM