簡體   English   中英

計算一組矩形和單個矩形之間差異的算法

[英]Algorithm to compute the difference between a set of rectangles and a single rectangle

假設我有一個紅色矩形,其坐標為(x,y)(x1,y)(x1,y1)(x,y1) ,它與未定義數量的不同藍色矩形(可能具有不同的寬度和/ 或高度)並隨機放置在一個表面上(它們甚至可能根本不與紅色矩形重疊)。 無論如何,是這樣的:

在此處輸入圖片說明

我將藍色矩形存儲在一個rectangles數組中,並且我也有每個藍色矩形的坐標。

現在,我需要做的是選擇紅色矩形中不與rectangles數組的任何藍色矩形重疊的部分(基本上我需要在所有藍色矩形和紅色矩形的並union之間進行區分) . 在前面的示例中,這些部分將是(由黑色邊框分隔):

在此處輸入圖片說明

而且,我需要從這些部分計算新的矩形,並將結果作為數組。 因此,之前的部分應該變成以下矩形:

在此處輸入圖片說明

或者下面的矩形(它們是如何生成的並不重要,當然越少越好(但看下圖我猜,考慮到它的一部分,不能少於n矩形,它們將始終是n ,在這種情況下n = 13 (如果我錯了,請糾正我))):

在此處輸入圖片說明

之后,我應該返回一個包含這些由紅色矩形部分創建的矩形的數組。

所以要求是:

  • 如果沒有藍色矩形與紅色矩形重疊,則返回一個包含紅色矩形數組
  • 如果有藍色矩形與紅色矩形重疊計算差值得到沒有與任何藍色矩形重疊的部分,並給定這些部分,划分每個部分,使每個部分由一個或多個矩形組成放置所有在數組中找到的矩形並返回該數組。

請注意,我們不是在類似網頁的表面上,這意味着x < x1像在網絡上( left < right ),但是y > y1 (而在網絡top < bottom ),因此我有以下Rectangle數據具有overlaps()方法的結構(偽代碼):

class Rectangle {
    this.x,
    this.x1,
    this.y,
    this.y1;

    /**
    * @constructor
    */
    Rectangle(x, y, x1, y1) {
        this.x = x;
        this.y = y;
        this.x1 = x1;
        this.y1 = y1;
    }

    /**
    * Tests whether this rectangle overlaps or is overlapped by the rectangle given as parameter.
    * 
    * @returns True if the rectangle is overlapped or overlaps the rectangle given as parameter, false otherwise.
    */
    Boolean overlaps(Rectangle rect) {
       compareX = function(coordX1, coordX2) {
          less = coordX1[0] > coordX2[0] ? coordX2: coordX1;
          greater = coordX1[0] > coordX2[0] ? coordX1: coordX2;
          return less[1] > greater[0] || less[0] == greater[0];

       }

       compareY = function(coordY1, coordY2) {
          less = coordY1[0] > coordY2[0] ? coordY2 : coordY1;           
          greater = coordY1[0] > coordY2[0] ? coordY1 : coordY2;
          return greater[1] < less[0] || greater[0] == less[0];
       }

       coordX1 = [this.x, this.x1]; // [] brackets create a new array
       coordX2 = [rect.x, rect.x1];
       coordY1 = [this.y, this.y1];
       coordY2 = [rect.y, rect.y1]
       return compareX(coordX1, coord) && compareY(coordY1, coordY2);
    } 
}

現在,計算差異矩形的有效方法是什么? (例如一個differenceRectangles函數)

    //...
    blueRectangles = [ blueRect1, blueRect2, blueRect3, ... ] // This is an array of blue rectangles, I don't know how many there are, but each item of the array is a `Rectangle` data structure with an `overlaps()` method
    redRectangle = new Rectangle(x, x1, y, y1);

    differenceRectangles = differenceRectangles(blueRectangles, redRectangle);

創建僅包含相關坐標的壓縮軸。 例如,x軸應包含xx1的外部矩形的加上所有xx1所有矩形的橫亘在大的矩形。 合並重復的坐標。

您現在有一個可能的矩形網格:

壓縮坐標網格

在這個例子中,你得到一個 6×5 的網格。

迭代所有矩形並將它們占據的網格單元標記為“孔”。 如果軸已排序並且有字典按坐標查找網格索引,則可以有效地完成此操作。 你得到:

已占用和空單元格

現在組合剩余的矩形。 例如,您可以連接水平相鄰的矩形:

解決方案的初稿

有改進的余地。 右下角的大紅色區域最好使用一個大矩形。 但作為初稿,這應該可行。

暫無
暫無

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

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