确定两个矩形是否相互重叠?
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));
}
这个答案应该是最好的答案:
如果矩形重叠,则重叠区域将大于零。现在让我们找到重叠区域:
如果它们重
以上是关于确定两个矩形是否相互重叠?的主要内容,如果未能解决你的问题,请参考以下文章