【问题标题】:Check if two rectangles overlap检查两个矩形是否重叠
【发布时间】:2017-05-13 06:14:14
【问题描述】:

这个问题已经问过很多次了,我看过很多帖子,但我的查询非常具体。如何查看两个矩形是否重叠。在我的代码中发现错误的测试用例是:

l2 = new RectanglePoint(0, 7);
r2 = new RectanglePoint(6, 10);
l1 = new RectanglePoint(0, 7);
r1 = new RectanglePoint(6, 0);
函数调用:isOverlap(new Rectangle(l1, r1), new Rectangle(l2, r2));

我的代码:

class RectanglePoint {
    int x;
    int y;

    public RectanglePoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

class Rectangle {
    RectanglePoint topLeft;
    RectanglePoint bottomRight;

    public Rectangle(RectanglePoint topLeft, RectanglePoint bottomRight) {
        this.topLeft = topLeft;
        this.bottomRight = bottomRight;
    }
}

public class RectangleOverlap {
    public boolean isOverlap(Rectangle rect1, Rectangle rect2) {
        return isOverlapHelper1(rect1.topLeft, rect1.bottomRight, rect2.topLeft,
                rect2.bottomRight);
    }


    private boolean isOverlapHelper1(RectanglePoint topLeftA,
            RectanglePoint bottomRightA, RectanglePoint topLeftB,
            RectanglePoint bottomRightB) {
        if (topLeftA.y < bottomRightB.y || topLeftB.y < bottomRightA.y) {
            return false;
        }
        if (topLeftA.x > bottomRightB.x || topLeftB.x > bottomRightA.x) {
            return false;
        }
        return true;
    }

bug 的条件是:if (topLeftA.y

请帮忙。我已经在这方面花费了很多时间。

【问题讨论】:

标签: java math data-structures rectangles


【解决方案1】:

您的条件if (topLeftA.y &lt; bottomRightB.y || topLeftB.y &lt; bottomRightA.y)(topLeftA.x &gt; bottomRightB.x || topLeftB.x &gt; bottomRightA.x) 假设属性topLeft 确实是矩形的左上角顶点,而bottomRight 确实是矩形的右下角顶点。但是,您的初始化代码 this.topLeft = topLeft;this.bottomRight = bottomRight; 实际上并不能保证这一点。如果初始化对矩形使用了错误的顶点,您的代码将无法更正该问题,以后的方法可能会出错。

这就是您的测试用例中发生的情况。您不清楚您的坐标是笛卡尔坐标(增加 y 值上升)还是图形坐标(增加 y 值下降)。但无论哪种情况,您的两个测试矩形中的一个都定义错误。您的第一个矩形从 (0, 7) 变为 (6, 0),这在笛卡尔坐标中是正确的,但在图形坐标中是错误的。您的第二个矩形从 (0, 7) 变为 (6, 10),这在图形坐标中是正确的,但在笛卡尔坐标中是错误的。无论您使用哪个坐标,其中一个矩形都是错误的,因此您的重叠代码会失败。

根据您的姓名,您应该在创建矩形时更正坐标,或者返回错误坐标。为了校正笛卡尔坐标,让 topLeft 的 x 坐标是两个给定顶点的 x 坐标的最小值,topLeft 的 y 坐标是两个给定顶点的 y 坐标的最大值,x- bottomRight 的坐标是两个给定顶点的 x 坐标的最大值,bottomRight 的 y 坐标是两个给定顶点的 y 坐标的最小值。然后调用者可以使用矩形的任意两个相对顶点并且仍然得到有效的结果。

【讨论】:

    【解决方案2】:

    您假设输入 l1l2 将始终是 topLeft 坐标,r1r2 将始终是 bottomRight 坐标。 为了遵守该假设,我建议您使用某种条件/验证来确保输入与您的假设一致,

    在调用isOverlapHelper1()之前在isOverlap()之前使用此代码

    if ((rect1.topLeft.x > rect1.bottomRight.x) ||
    (rect1.topLeft.y < rect1.bottomRight.y) ||
    (rect2.topLeft.x > rect2.bottomRight.x) || 
    (rect2.topLeft.y < rect2.bottomRight.y))
      throw new IllegalArgumentException("Wrong co-ordinates");
    

    上述条件的简化:

    1. TopLeft 的X 坐标应该小于BottomRight 的X 坐标
    2. TopLeft 的 Y 坐标应大于 BottomRight 的 Y 坐标


    或者你可以在构造函数Rectangle()中检查这个

    如需更简单且独立于语言的解释,请查看my answer on a similar thread

    【讨论】:

      猜你喜欢
      • 2018-09-29
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2015-06-01
      相关资源
      最近更新 更多