Java方法找到两个矩形的交集,只使用左下点,宽度和高度?

2022-09-05 00:20:51

我已经找到了解决方案,但希望确保我的逻辑是最有效的。我觉得有更好的方法。我有左下角的(x,y)坐标,2个矩形的高度和宽度,我需要返回第三个矩形,这是它们的交集。我不想发布代码,因为我觉得这是作弊。

  1. 我弄清楚图表上哪个最左边和最高。
  2. 我检查一个是否完全重叠另一个,然后反转以查看另一个是否完全重叠X轴上的第一个。
  3. 我检查 X 轴上的部分交集。
  4. 我基本上对Y轴重复步骤2和3。
  5. 我做了一些数学运算,并根据这些条件获得矩形的点。

我可能过度思考这个问题,编写了低效的代码。我已经交出了一个工作程序,但想找到我自己的知识的最佳方式。如果有人能同意或为我指出正确的方向,那就太好了!


答案 1

为什么不使用 JDK API 为您执行此操作呢?

Rectangle rect1 = new Rectangle(100, 100, 200, 240);
Rectangle rect2 = new Rectangle(120, 80, 80, 120);
Rectangle intersection = rect1.intersection(rect2);

要使用类,构造函数的参数是:x,y,宽度,高度,其中x,y是矩形的左上角。您可以轻松地将左下角的点转换为左上角。java.awt.Rectangle


我推荐上述内容,但如果您真的想自己动手,可以按照以下步骤操作:

分别是 Rect1 的左下角和右下角,分别是 Rect2 的左下角和右下角。(x1, y1), (x2, y2)(x3, y3), (x4, y4)

  • 分别找到 较大的一个 , 和 较小的一个 , , 说 ,x1x3x2x4xLxR
    • 如果 ,则不返回其他交集xL >= xR
  • 分别找到 较大的一个 , 和 较小的一个 , , 说 ,y1y3y2y4yTyB
    • 如果 ,则不返回其他交集yT >= yB
    • 返回。(xL, yB, xR-xL, yB-yT)

一个更像Java的伪代码:

// Two rectangles, assume the class name is `Rect`
Rect r1 = new Rect(x1, y2, w1, h1);
Rect r2 = new Rect(x3, y4, w2, h2);

// get the coordinates of other points needed later:
int x2 = x1 + w1;
int x4 = x3 + w2;
int y1 = y2 - h1;
int y3 = y4 - h2;

// find intersection:
int xL = Math.max(x1, x3);
int xR = Math.min(x2, x4);
if (xR <= xL)
    return null;
else {
    int yT = Math.max(y1, y3);
    int yB = Math.min(y2, y4);
    if (yB <= yT)
        return null;
    else
        return new Rect(xL, yB, xR-xL, yB-yT);
}

如您所见,如果您的矩形最初是由两个对角定义的,那将更容易,您只需要做部分。// find intersection


答案 2

我在一个小效用函数中确定两个矩形的交集的变体。

//returns true when intersection is found, false otherwise.
//when returning true, rectangle 'out' holds the intersection of r1 and r2.
private static boolean intersection2(Rectangle r1, Rectangle r2,
        Rectangle out) {
    float xmin = Math.max(r1.x, r2.x);
    float xmax1 = r1.x + r1.width;
    float xmax2 = r2.x + r2.width;
    float xmax = Math.min(xmax1, xmax2);
    if (xmax > xmin) {
        float ymin = Math.max(r1.y, r2.y);
        float ymax1 = r1.y + r1.height;
        float ymax2 = r2.y + r2.height;
        float ymax = Math.min(ymax1, ymax2);
        if (ymax > ymin) {
            out.x = xmin;
            out.y = ymin;
            out.width = xmax - xmin;
            out.height = ymax - ymin;
            return true;
        }
    }
    return false;
}