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

有什么建议吗?


当前回答

下面是如何在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));
}

其他回答

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/

更容易检查一个矩形是否完全在另一个矩形之外,如果它是其中之一

在左边……

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

如果只在触摸时得到阳性结果,我们可以通过“<=”和“>=”来更改“<”和“>”。

在问题中,你链接到矩形旋转角度任意时的数学。然而,如果我理解了问题中关于角度的部分,我就会理解为所有的矩形都是相互垂直的。

一般已知重叠面积的公式为:

举个例子:

   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坐标之间的间隙数量创建一个2D数组。

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

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