簡體   English   中英

確定兩個矩形是否相互重疊?

[英]Determine if two rectangles overlap each other?

我正在嘗試編寫一個 C++ 程序,它從用戶那里獲取以下輸入來構造矩形(2 到 5 之間):高度、寬度、x-pos、y-pos。 所有這些矩形都將平行於 x 軸和 y 軸存在,也就是說,它們的所有邊都將具有 0 或無窮大的斜率。

我試圖實現這個問題中提到的內容,但我運氣不佳。

我當前的實現執行以下操作:

// Gets all the vertices for Rectangle 1 and stores them in an array -> arrRect1
// point 1 x: arrRect1[0], point 1 y: arrRect1[1] and so on...
// Gets all the vertices for Rectangle 2 and stores them in an array -> arrRect2

// rotated edge of point a, rect 1
int rot_x, rot_y;
rot_x = -arrRect1[3];
rot_y = arrRect1[2];
// point on rotated edge
int pnt_x, pnt_y;
pnt_x = arrRect1[2]; 
pnt_y = arrRect1[3];
// test point, a from rect 2
int tst_x, tst_y;
tst_x = arrRect2[0];
tst_y = arrRect2[1];

int value;
value = (rot_x * (tst_x - pnt_x)) + (rot_y * (tst_y - pnt_y));
cout << "Value: " << value;  

但是,我不太確定 (a) 我是否已經正確實現了鏈接到的算法,或者我是否確實如何解釋它?

有什么建議?

if (RectA.Left < RectB.Right && RectA.Right > RectB.Left &&
     RectA.Top > RectB.Bottom && RectA.Bottom < RectB.Top ) 

或者,使用笛卡爾坐標

(X1 是左坐標,X2 是右坐標,從左到右增加,Y1 是頂坐標,Y2 是底坐標,從底到頂增加——如果這不是你的坐標系[例如大多數計算機都有Y 方向反轉],交換下面的比較)...

if (RectA.X1 < RectB.X2 && RectA.X2 > RectB.X1 &&
    RectA.Y1 > RectB.Y2 && RectA.Y2 < RectB.Y1) 

假設你有矩形 A 和矩形 B。證明是矛盾的。 四個條件中的任何一個都保證不存在重疊

  • 條件 1。 如果 A 的左邊緣在 B 右邊緣的右側,那么 A 完全在 B 的右側
  • 條件 2。 如果 A 的右邊緣在 B 左邊緣的左邊,那么 A 完全在 B 的左邊
  • 條件 3。 如果 A 的頂部邊緣低於 B 的底部邊緣, - 那么 A 完全低於 B
  • 條件 4。 如果 A 的底邊高於 B 的頂邊, - 那么 A 完全高於 B

所以非重疊的條件是

NON-Overlap => Cond1 Or Cond2 Or Cond3 Or Cond4

因此,Overlap 的充分條件是相反的。

Overlap => NOT (Cond1 Or Cond2 Or Cond3 Or Cond4)

德摩根定律說
Not (A or B or C or D)Not A And Not B And Not C And Not D
所以使用德摩根,我們有

Not Cond1 And Not Cond2 And Not Cond3 And Not Cond4

這相當於:

  • A 的左邊緣到 B 的右邊緣的左側,[ RectA.Left < RectB.Right ],和
  • A 的右邊緣到 B 的左邊緣的右側,[ RectA.Right > RectB.Left ],以及
  • A 的頂部高於 B 的底部,[ RectA.Top > RectB.Bottom ],以及
  • A 的底部低於 B 的頂部 [ RectA.Bottom < RectB.Top ]

注 1 :很明顯,同樣的原則可以擴展到任意數量的維度。
注意 2 :計算一個像素的重疊也應該是相當明顯的,將該邊界上的<和/或>更改為<=>=
注 3 :這個答案,當使用笛卡爾坐標 (X, Y) 時基於標准代數笛卡爾坐標(x 從左到右增加,Y 從下到上增加)。 顯然,如果計算機系統可能會以不同的方式機械化屏幕坐標(例如,從上到下增加 Y,或從右到左增加 X),則需要相應地調整語法/

struct rect
{
    int x;
    int y;
    int width;
    int height;
};

bool valueInRange(int value, int min, int max)
{ return (value >= min) && (value <= max); }

bool rectOverlap(rect A, rect B)
{
    bool xOverlap = valueInRange(A.x, B.x, B.x + B.width) ||
                    valueInRange(B.x, A.x, A.x + A.width);

    bool yOverlap = valueInRange(A.y, B.y, B.y + B.height) ||
                    valueInRange(B.y, A.y, A.y + A.height);

    return xOverlap && yOverlap;
}
struct Rect
{
    Rect(int x1, int x2, int y1, int y2)
    : x1(x1), x2(x2), y1(y1), y2(y2)
    {
        assert(x1 < x2);
        assert(y1 < y2);
    }

    int x1, x2, y1, y2;
};

bool
overlap(const Rect &r1, const Rect &r2)
{
    // The rectangles don't overlap if
    // one rectangle's minimum in some dimension 
    // is greater than the other's maximum in
    // that dimension.

    bool noOverlap = r1.x1 > r2.x2 ||
                     r2.x1 > r1.x2 ||
                     r1.y1 > r2.y2 ||
                     r2.y1 > r1.y2;

    return !noOverlap;
}

檢查一個矩形是否完全在另一個矩形之外更容易,所以如果它是

在左邊...

(r1.x + r1.width < r2.x)

或者在右邊...

(r1.x > r2.x + r2.width)

或者在上面...

(r1.y + r1.height < r2.y)

或者在底部...

(r1.y > r2.y + r2.height)

的第二個矩形,它不可能與它碰撞。 因此,要獲得一個返回布爾值的函數,表示矩形發生碰撞,我們只需通過邏輯 OR 組合條件並否定結果:

function checkOverlap(r1, r2) : Boolean
{ 
    return !(r1.x + r1.width < r2.x || r1.y + r1.height < r2.y || r1.x > r2.x + r2.width || r1.y > r2.y + r2.height);
}

為了僅在觸摸時已經收到肯定的結果,我們可以將“<”和“>”更改為“<=”和“>=”。

假設您已經定義了矩形的位置和大小,如下所示:

在此處輸入圖片說明

我的 C++ 實現是這樣的:

class Vector2D
{
    public:
        Vector2D(int x, int y) : x(x), y(y) {}
        ~Vector2D(){}
        int x, y;
};

bool DoRectanglesOverlap(   const Vector2D & Pos1,
                            const Vector2D & Size1,
                            const Vector2D & Pos2,
                            const Vector2D & Size2)
{
    if ((Pos1.x < Pos2.x + Size2.x) &&
        (Pos1.y < Pos2.y + Size2.y) &&
        (Pos2.x < Pos1.x + Size1.x) &&
        (Pos2.y < Pos1.y + Size1.y))
    {
        return true;
    }
    return false;
}

根據上圖給出的示例函數調用:

DoRectanglesOverlap(Vector2D(3, 7),
                    Vector2D(8, 5),
                    Vector2D(6, 4),
                    Vector2D(9, 4));

if塊內的比較如下所示:

if ((Pos1.x < Pos2.x + Size2.x) &&
    (Pos1.y < Pos2.y + Size2.y) &&
    (Pos2.x < Pos1.x + Size1.x) &&
    (Pos2.y < Pos1.y + Size1.y))
                 ↓  
if ((   3   <    6   +   9    ) &&
    (   7   <    4   +   4    ) &&
    (   6   <    3   +   8    ) &&
    (   4   <    7   +   5    ))

問自己相反的問題:如何確定兩個矩形是否根本不相交? 顯然,完全位於矩形 B 左側的矩形 A 不相交。 同樣,如果 A 完全向右。 同樣,如果 A 完全高於 B 或完全低於 B。在任何其他情況下,A 和 B 相交。

下面的內容可能有錯誤,但我對算法非常有信心:

struct Rectangle { int x; int y; int width; int height; };

bool is_left_of(Rectangle const & a, Rectangle const & b) {
   if (a.x + a.width <= b.x) return true;
   return false;
}
bool is_right_of(Rectangle const & a, Rectangle const & b) {
   return is_left_of(b, a);
}

bool not_intersect( Rectangle const & a, Rectangle const & b) {
   if (is_left_of(a, b)) return true;
   if (is_right_of(a, b)) return true;
   // Do the same for top/bottom...
 }

bool intersect(Rectangle const & a, Rectangle const & b) {
  return !not_intersect(a, b);
}

如果兩個矩形重疊,這是使用 C++ 檢查的一種非常快速的方法:

return std::max(rectA.left, rectB.left) < std::min(rectA.right, rectB.right)
    && std::max(rectA.top, rectB.top) < std::min(rectA.bottom, rectB.bottom);

它的工作原理是計算相交矩形的左右邊界,然后比較它們:如果右邊界等於或小於左邊界,則表示相交為空,因此矩形不重疊; 否則,它會再次嘗試使用頂部和底部邊框。

與傳統的 4 次比較替代方法相比,這種方法有什么優勢? 這是關於現代處理器的設計方式。 他們有一種叫做分支預測的東西,當比較的結果總是相同的時候它工作得很好,但否則會有巨大的性能損失。 但是,在沒有分支指令的情況下,CPU 的表現相當不錯。 通過計算交點的邊界而不是對每個軸進行兩次單獨的檢查,我們節省了兩個分支,每對一個。

如果第一個比較很可能是錯誤的,那么四次比較方法可能會優於這個方法。 不過,這種情況非常罕見,因為這意味着第二個矩形通常位於第一個矩形的左側,而不是右側或與其重疊; 大多數情況下,您需要檢查第一個矩形兩側的矩形,這通常會抵消分支預測的優勢。

此方法可以進一步改進,具體取決於矩形的預期分布:

  • 如果您希望選中的矩形主要位於彼此的左側或右側,那么上述方法效果最佳。 例如,當您使用矩形交集檢查游戲的碰撞時,可能就是這種情況,其中游戲對象主要是水平分布的(例如,類似 SuperMarioBros 的游戲)。
  • 如果您希望選中的矩形主要位於彼此的頂部或底部,例如在冰塔類型的游戲中,那么首先檢查頂部/底部和最后左側/右側可能會更快:
return std::max(rectA.top, rectB.top) < std::min(rectA.bottom, rectB.bottom)
    && std::max(rectA.left, rectB.left) < std::min(rectA.right, rectB.right);
  • 如果相交的概率接近於不相交的概率,那么最好有一個完全無分支的替代方案:
return std::max(rectA.left, rectB.left) < std::min(rectA.right, rectB.right)
     & std::max(rectA.top, rectB.top) < std::min(rectA.bottom, rectB.bottom);

(注意將&&更改為單個&

下面是它在 Java API 中的實現方式:

public boolean intersects(Rectangle r) {
    int tw = this.width;
    int th = this.height;
    int rw = r.width;
    int rh = r.height;
    if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
        return false;
    }
    int tx = this.x;
    int ty = this.y;
    int rx = r.x;
    int ry = r.y;
    rw += rx;
    rh += ry;
    tw += tx;
    th += ty;
    //      overflow || intersect
    return ((rw < rx || rw > tx) &&
            (rh < ry || rh > ty) &&
            (tw < tx || tw > rx) &&
            (th < ty || th > ry));
}

在這個問題中,您鏈接到矩形處於任意旋轉角度時的數學。 但是,如果我理解問題中關於角度的一點,我會解釋所有矩形都相互垂直。

一般知道重疊面積公式是:

使用示例:

1   2   3   4   5   6

1  +---+---+
   |       |   
2  +   A   +---+---+
   |       | B     |
3  +       +   +---+---+
   |       |   |   |   |
4  +---+---+---+---+   +
               |       |
5              +   C   +
               |       |
6              +---+---+

1)將所有x坐標(左右)收集到一個列表中,然后對其進行排序並刪除重復項

1 3 4 5 6

2)將所有y坐標(頂部和底部)收集到一個列表中,然后對其進行排序並刪除重復項

1 2 3 4 6

3) 通過唯一 x 坐標之間的間隙數 * 唯一 y 坐標之間的間隙數創建一個二維數組。

4 * 4

4) 將所有矩形繪制到這個網格中,增加它出現的每個單元格的計數:

1   3   4   5   6

1  +---+
   | 1 | 0   0   0
2  +---+---+---+
   | 1 | 1 | 1 | 0
3  +---+---+---+---+
   | 1 | 1 | 2 | 1 |
4  +---+---+---+---+
     0   0 | 1 | 1 |
6          +---+---+

5) 在繪制矩形時,很容易截取重疊部分。

struct Rect
{
   Rect(int x1, int x2, int y1, int y2)
   : x1(x1), x2(x2), y1(y1), y2(y2)
   {
       assert(x1 < x2);
       assert(y1 < y2);
   }

   int x1, x2, y1, y2;
};

//some area of the r1 overlaps r2
bool overlap(const Rect &r1, const Rect &r2)
{
    return r1.x1 < r2.x2 && r2.x1 < r1.x2 &&
           r1.y1 < r2.y2 && r2.x1 < r1.y2;
}

//either the rectangles overlap or the edges touch
bool touch(const Rect &r1, const Rect &r2)
{
    return r1.x1 <= r2.x2 && r2.x1 <= r1.x2 &&
           r1.y1 <= r2.y2 && r2.x1 <= r1.y2;
}

假設這兩個矩形是矩形 A 和矩形 B。 設它們的中心為 A1 和 B1(A1 和 B1 的坐標很容易找到),設高度為 Ha 和 Hb,寬度為 Wa 和 Wb,設 dx 為A1 和 B1 之間的寬度(x)距離和 dy 是 A1 和 B1 之間的高度(y)距離。

現在我們可以說我們可以說 A 和 B 重疊:當

if(!(dx > Wa+Wb)||!(dy > Ha+Hb)) returns true

最簡單的方法是

/**
 * Check if two rectangles collide
 * x_1, y_1, width_1, and height_1 define the boundaries of the first rectangle
 * x_2, y_2, width_2, and height_2 define the boundaries of the second rectangle
 */
boolean rectangle_collision(float x_1, float y_1, float width_1, float height_1, float x_2, float y_2, float width_2, float height_2)
{
  return !(x_1 > x_2+width_2 || x_1+width_1 < x_2 || y_1 > y_2+height_2 || y_1+height_1 < y_2);
}

首先要記住,在計算機中坐標系是顛倒的。 x 軸與數學中的相同,但 y 軸向下增加,向上減少。如果從中心繪制矩形。 如果 x1 坐標大於 x2 加上其寬度的一半。 那么這意味着走一半他們會互相接觸。 並以同樣的方式向下+一半高度。 會碰撞。。

不要將坐標視為指示像素所在的位置。 將它們視為在像素之間。 這樣,2x2 矩形的面積應該是 4,而不是 9。

bool bOverlap = !((A.Left >= B.Right || B.Left >= A.Right)
               && (A.Bottom >= B.Top || B.Bottom >= A.Top));

我有一個非常簡單的解決方案

讓 x1,y1 x2,y2 ,l1,b1,l2,be 分別為它們的坐標和長度和寬度

考慮條件 ((x2

現在,這些矩形重疊的唯一方式是,x1,y1 的對角線點是否位於另一個矩形內,或者類似地,x2,y2 的對角線點將位於另一個矩形內。 這正是上述條件所暗示的。

A和B是兩個矩形。 C 是它們的覆蓋矩形。

four points of A be (xAleft,yAtop),(xAleft,yAbottom),(xAright,yAtop),(xAright,yAbottom)
four points of A be (xBleft,yBtop),(xBleft,yBbottom),(xBright,yBtop),(xBright,yBbottom)

A.width = abs(xAleft-xAright);
A.height = abs(yAleft-yAright);
B.width = abs(xBleft-xBright);
B.height = abs(yBleft-yBright);

C.width = max(xAleft,xAright,xBleft,xBright)-min(xAleft,xAright,xBleft,xBright);
C.height = max(yAtop,yAbottom,yBtop,yBbottom)-min(yAtop,yAbottom,yBtop,yBbottom);

A and B does not overlap if
(C.width >= A.width + B.width )
OR
(C.height >= A.height + B.height) 

它會處理所有可能的情況。

如果矩形重疊,則重疊面積將大於零。 現在讓我們找到重疊區域:

如果它們重疊,那么重疊矩形的左邊緣將是max(r1.x1, r2.x1) ,右邊緣將是min(r1.x2, r2.x2) 所以重疊的長度將是min(r1.x2, r2.x2) - max(r1.x1, r2.x1)

所以該區域將是:

area = (max(r1.x1, r2.x1) - min(r1.x2, r2.x2)) * (max(r1.y1, r2.y1) - min(r1.y2, r2.y2))

如果area = 0則它們不重疊。

是不是很簡單?

我已經實現了一個 C# 版本,它很容易轉換為 C++。

public bool Intersects ( Rectangle rect )
{
  float ulx = Math.Max ( x, rect.x );
  float uly = Math.Max ( y, rect.y );
  float lrx = Math.Min ( x + width, rect.x + rect.width );
  float lry = Math.Min ( y + height, rect.y + rect.height );

  return ulx <= lrx && uly <= lry;
}

這是來自 Java 編程簡介 - 綜合版一書的練習 3.28。 代碼測試兩個矩形是否為齒形,一個矩形是否在另一個矩形內,一個矩形是否在另一個矩形外部。 如果這些條件都不滿足,則兩者重疊。

**3.28(幾何:兩個矩形)編寫一個程序,提示用戶輸入兩個矩形的中心 x、y 坐標、寬度和高度,並確定第二個矩形是在第一個矩形內部還是與第一個矩形重疊,如圖 3.9 所示。 測試您的程序以涵蓋所有情況。 以下是示例運行:

輸入 r1 的中心 x、y 坐標、寬度和高度:2.5 4 2.5 43 輸入 r2 的中心 x、y 坐標、寬度和高度:1.5 5 0.5 3 r2 在 r1 內

輸入 r1 的中心 x、y 坐標、寬度和高度:1 2 3 5.5 輸入 r2 的中心 x、y 坐標、寬度和高度:3 4 4.5 5 r2 與 r1 重疊

輸入r1的中心x、y坐標、寬度和高度:1 2 3 3 輸入r2的中心x、y坐標、寬度和高度:40 45 3 2 r2不與r1重疊

import java.util.Scanner;

public class ProgrammingEx3_28 {
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    System.out
            .print("Enter r1's center x-, y-coordinates, width, and height:");
    double x1 = input.nextDouble();
    double y1 = input.nextDouble();
    double w1 = input.nextDouble();
    double h1 = input.nextDouble();
    w1 = w1 / 2;
    h1 = h1 / 2;
    System.out
            .print("Enter r2's center x-, y-coordinates, width, and height:");
    double x2 = input.nextDouble();
    double y2 = input.nextDouble();
    double w2 = input.nextDouble();
    double h2 = input.nextDouble();
    w2 = w2 / 2;
    h2 = h2 / 2;

    // Calculating range of r1 and r2
    double x1max = x1 + w1;
    double y1max = y1 + h1;
    double x1min = x1 - w1;
    double y1min = y1 - h1;
    double x2max = x2 + w2;
    double y2max = y2 + h2;
    double x2min = x2 - w2;
    double y2min = y2 - h2;

    if (x1max == x2max && x1min == x2min && y1max == y2max
            && y1min == y2min) {
        // Check if the two are identicle
        System.out.print("r1 and r2 are indentical");

    } else if (x1max <= x2max && x1min >= x2min && y1max <= y2max
            && y1min >= y2min) {
        // Check if r1 is in r2
        System.out.print("r1 is inside r2");
    } else if (x2max <= x1max && x2min >= x1min && y2max <= y1max
            && y2min >= y1min) {
        // Check if r2 is in r1
        System.out.print("r2 is inside r1");
    } else if (x1max < x2min || x1min > x2max || y1max < y2min
            || y2min > y1max) {
        // Check if the two overlap
        System.out.print("r2 does not overlaps r1");
    } else {
        System.out.print("r2 overlaps r1");
    }

}
}
bool Square::IsOverlappig(Square &other)
{
    bool result1 = other.x >= x && other.y >= y && other.x <= (x + width) && other.y <= (y + height); // other's top left falls within this area
    bool result2 = other.x >= x && other.y <= y && other.x <= (x + width) && (other.y + other.height) <= (y + height); // other's bottom left falls within this area
    bool result3 = other.x <= x && other.y >= y && (other.x + other.width) <= (x + width) && other.y <= (y + height); // other's top right falls within this area
    bool result4 = other.x <= x && other.y <= y && (other.x + other.width) >= x && (other.y + other.height) >= y; // other's bottom right falls within this area
    return result1 | result2 | result3 | result4;
}

對於那些在矩形數據中使用中心點和半尺寸的人,而不是典型的 x,y,w,h 或 x0,y0,x1,x1,您可以這樣做:

#include <cmath> // for fabsf(float)

struct Rectangle
{
    float centerX, centerY, halfWidth, halfHeight;
};

bool isRectangleOverlapping(const Rectangle &a, const Rectangle &b)
{
    return (fabsf(a.centerX - b.centerX) <= (a.halfWidth + b.halfWidth)) &&
           (fabsf(a.centerY - b.centerY) <= (a.halfHeight + b.halfHeight)); 
}
struct point { int x, y; };

struct rect { point tl, br; }; // top left and bottom right points

// return true if rectangles overlap
bool overlap(const rect &a, const rect &b)
{
    return a.tl.x <= b.br.x && a.br.x >= b.tl.x && 
           a.tl.y >= b.br.y && a.br.y <= b.tl.y;
}

就這么簡單……

   bool Intersect = RectA.IntersectsWith(RectB);

“如果您對每個矩形的兩個頂點對應的 x 或 y 坐標執行減法,如果結果相同,則兩個矩形不重疊軸”(對不起,我不確定我的翻譯是否正確)

在此處輸入圖片說明

資料來源: http : //www.ieev.org/2009/05/kiem-tra-hai-hinh-chu-nhat-c​​hong-nhau.html

用於確定矩形是否相互接觸或重疊的 Java 代碼

...

for ( int i = 0; i < n; i++ ) {
    for ( int j = 0; j < n; j++ ) {
        if ( i != j ) {
            Rectangle rectangle1 = rectangles.get(i);
            Rectangle rectangle2 = rectangles.get(j);

            int l1 = rectangle1.l; //left
            int r1 = rectangle1.r; //right
            int b1 = rectangle1.b; //bottom
            int t1 = rectangle1.t; //top

            int l2 = rectangle2.l;
            int r2 = rectangle2.r;
            int b2 = rectangle2.b;
            int t2 = rectangle2.t;

            boolean topOnBottom = t2 == b1;
            boolean bottomOnTop = b2 == t1;
            boolean topOrBottomContact = topOnBottom || bottomOnTop;

            boolean rightOnLeft = r2 == l1;
            boolean leftOnRight = l2 == r1;
            boolean rightOrLeftContact = leftOnRight || rightOnLeft;

            boolean leftPoll = l2 <= l1 && r2 >= l1;
            boolean rightPoll = l2 <= r1 && r2 >= r1;
            boolean leftRightInside = l2 >= l1 && r2 <= r1;
            boolean leftRightPossiblePlaces = leftPoll || rightPoll || leftRightInside;

            boolean bottomPoll = t2 >= b1 && b2 <= b1;
            boolean topPoll = b2 <= b1 && t2 >= b1;
            boolean topBottomInside = b2 >= b1 && t2 <= t1;
            boolean topBottomPossiblePlaces = bottomPoll || topPoll || topBottomInside;


            boolean topInBetween = t2 > b1 && t2 < t1;
            boolean bottomInBetween = b2 > b1 && b2 < t1;
            boolean topBottomInBetween = topInBetween || bottomInBetween;

            boolean leftInBetween = l2 > l1 && l2 < r1;
            boolean rightInBetween = r2 > l1 && r2 < r1;
            boolean leftRightInBetween = leftInBetween || rightInBetween;

            if ( (topOrBottomContact && leftRightPossiblePlaces) || (rightOrLeftContact && topBottomPossiblePlaces) ) {
                path[i][j] = true;
            }
        }
    }
}

...

從另一個站點看問題。

如果我們從另一側看問題(算法),則情況非常簡單

這意味着我們將回答問題:“矩形重疊嗎?”,而不是回答“矩形是否重疊?”的問題。

最后,兩個問題都解決了相同的問題,但是第二個問題的答案更易於實現,因為矩形僅在一個位於另一個下方或一個位於另一個左側時才重疊(對於一個矩形就足夠了)發生這些情況,但是當然可能會同時發生-在這里,對邏輯條件“或”的良好理解很重要)。 這減少了許多在第一個問題上需要考慮的情況。

使用適當的變量名也可以簡化整個過程:

#include<bits/stdc++.h> 

struct Rectangle
{ 
    // Coordinates of the top left corner of the rectangle and width and height
    float x, y, width, height; 
}; 

bool areRectanglesOverlap(Rectangle rect1, Rectangle rect2) 
{
  // Declaration and initialization of local variables

  // if x and y are the top left corner of the rectangle
  float left1, top1, right1, bottom1, left2, top2, right2, bottom2;
  left1 = rect1.x;
  top1 = rect1.y;
  right1 = rect1.x + rect1.width;
  bottom1 = rect1.y - rect1.height;
  left2 = rect2.x;
  top2 = rect2.y;
  right2 = rect2.x + rect2.width;
  bottom2 = rect2.y - rect2.height;

  // The main part of the algorithm

  // The first rectangle is under the second or vice versa
  if (top1 < bottom2 || top2 < bottom1)
  {
    return false;
  }
  // The first rectangle is to the left of the second or vice versa
  if (right1 < left2 || right2 < left1)
  {
    return false;
  }
  // Rectangles overlap
  return true;
}

即使我們有不同的矩形表示形式,也可以通過僅修改定義了變量更改的部分來使上面的函數適應於它。 函數的其他部分保持不變(當然,這里實際上並不需要注釋,但我添加了注釋,以便每個人都可以快速理解此簡單算法)。

以上功能等效 形式,但可讀性較低可能看起來像這樣:

bool areRectanglesOverlap(Rectangle rect1, Rectangle rect2) 
{
  float left1, top1, right1, bottom1, left2, top2, right2, bottom2;
  left1 = rect1.x;
  top1 = rect1.y;
  right1 = rect1.x + rect1.width;
  bottom1 = rect1.y - rect1.height;
  left2 = rect2.x;
  top2 = rect2.y;
  right2 = rect2.x + rect2.width;
  bottom2 = rect2.y - rect2.height;

  return !(top1 < bottom2 || top2 < bottom1 || right1 < left2 || right2 < left1);
}

暫無
暫無

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

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