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

有什么建议吗?


当前回答

最简单的方法是

/**
 * 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));
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/

如果矩形重叠,那么重叠面积将大于零。现在让我们求出重叠区域:

如果它们重叠,那么overlap-rect的左边缘将是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++实现是这样的:

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    ))

最简单的方法是

/**
 * 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加上它的一半宽。然后这意味着他们会互相接触。用同样的方法向下+一半高。它会碰撞的。