我试图写一个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)我是否已经正确地实现了我链接的算法,或者如果我确实如何解释这一点?

有什么建议吗?


当前回答

我有一个很简单的解决办法

设x1, y1x2,y2,l1,b1,l2分别为它们的坐标和长、宽

考虑条件((x2 现在,这两个矩形重叠的唯一方式是,如果点(x1,y1)的对角线在另一个矩形内或者类似地,点(x2,y2)的对角线在另一个矩形内。这正是上面的条件所暗示的。

其他回答

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。 反证法是证明。四个条件中的任何一个都保证不存在重叠:

Cond1。如果A的左边在B的右边的右边, -那么A完全在B的右边 Cond2。如果A的右边在B的左边的左边, -那么A完全在B的左边 Cond3。如果A的上边在B的下边之下, -那么A完全低于B Cond4。如果A的下边在B的上边上面, -那么A完全高于B

不重叠的条件是

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

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

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

德摩根定律说 不是(A或B或C或D)和不是A不是B不是C不是D是一样的 所以利用德·摩根,我们有

Not Cond1 And Not Cond2 And Not Cond3 And Not Cond4

这相当于:

A的左边到B的右边的左边,[RectA。左< RectB。正确的), A的右边到B的左边的右边,[RectA。对,>,RectB。左), A的顶部高于B的底部。Top > RectB。底), A的底部在B的顶部以下。底部< RectB。前)

Note 1: It is fairly obvious this same principle can be extended to any number of dimensions. Note 2: It should also be fairly obvious to count overlaps of just one pixel, change the < and/or the > on that boundary to a <= or a >=. Note 3: This answer, when utilizing Cartesian coordinates (X, Y) is based on standard algebraic Cartesian coordinates (x increases left to right, and Y increases bottom to top). Obviously, where a computer system might mechanize screen coordinates differently, (e.g., increasing Y from top to bottom, or X From right to left), the syntax will need to be adjusted accordingly/

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

这是来自《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");
    }

}
}