我试图写一个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编程入门-综合版》中的练习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");
    }

}
}

其他回答

我已经实现了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;
}
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;
}
struct point { int x, y; };

struct rect { point tl, br; }; // top left and bottom right points

// return true if rectangles overlap
bool overlap(const rect &a, const rect &b)
{
    return a.tl.x <= b.br.x && a.br.x >= b.tl.x && 
           a.tl.y >= b.br.y && a.br.y <= b.tl.y;
}

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

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

举个例子:

   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)当你绘制矩形时,很容易截取重叠部分。

最简单的方法是

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