确定两个矩形是否相互重叠?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了确定两个矩形是否相互重叠?相关的知识,希望对你有一定的参考价值。

我正在尝试编写一个C ++程序,它从用户那里获取以下输入来构造矩形(2到5之间):高度,宽度,x-pos,y-pos。所有这些矩形将平行于x轴和y轴存在,即它们的所有边都将具有0或无穷大的斜率。

我试图实现this问题中提到的但我没有太多运气。

我目前的实现如下:

// 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为底部坐标,从下到上增加)......

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

注意:对于所有具有编辑权限的用户。请停止使用此信息。

假设您有Rect A和Rect B.证明是矛盾的。四个条件中的任何一个都保证不存在重叠:

  • COND1。如果A的左边缘位于B的右边缘的右边,那么A就完全在B的右边
  • COND2。如果A的右边缘位于B的左边缘的左边,那么A则完全在B的左边
  • COND3。如果A的上边缘低于B的下边缘,则A完全低于B
  • COND4。如果A的下边缘高于B的上边缘,那么A完全高于B

所以非重叠的条件是

Cond1 Or Cond2 Or Cond3 Or Cond4

因此,重叠的充分条件恰恰相反。

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相同 所以使用De Morgan,我们有

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),语法将需要相应地调整/

另一答案

不要将坐标视为指示像素的位置。把它们想象成像素之间。这样,2x2矩形的面积应为4,而不是9。

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

最简单的方法是

/**
 * 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加上它的一半widht。那意味着他们会相互接触一半。并以相同的方式向下+高度的一半。它会碰撞..

另一答案

让我们说两个矩形是矩形A和矩形B.让中心是A1和B1(A1和B1的坐标很容易找到),高度为Ha和Hb,宽度为Wa和Wb,让dx为width(x)A1和B1之间的距离,dy是A1和B1之间的高度(y)距离。

现在我们可以说我们可以说A和B重叠:何时

if(!(dx > Wa+Wb)||!(dy > Ha+Hb)) returns true
另一答案

我已经实现了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;
}
另一答案

我有一个非常简单的解决方案

令x1,y1 x2,y2,l1,b1,l2分别为它们的坐标,长度和宽度

考虑条件((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) 

它会照顾所有可能的情况。

另一答案

这是来自Java编程简介 - 综合版的练习3.28。代码测试两个矩形是否为indenticle,一个是否在另一个内部以及一个是否在另一个之外。如果这些条件都不满足则两者重叠。

** 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)); 
}
另一答案

这个答案应该是最好的答案:

如果矩形重叠,则重叠区域将大于零。现在让我们找到重叠区域:

如果它们重

以上是关于确定两个矩形是否相互重叠?的主要内容,如果未能解决你的问题,请参考以下文章

给定两个矩形的坐标,找出矩形是不是重叠

将对象的边缘相互对齐并防止重叠

C++编程,求俩矩形重叠面积的代码

矩形重叠

如何修复重叠的片段

片段相互重叠