1. 概述
在本篇文章中,我们将探讨一个经典的算法问题:如何判断两个给定的矩形是否重叠。这个问题在图形处理、碰撞检测等场景中非常常见。
我们会从问题定义出发,逐步推导解决方案,并最终用 Java 实现。
2. 问题定义
假设我们有两个矩形 r1
和 r2
,我们需要判断它们之间是否存在至少一个公共点。如果存在,则说明这两个矩形发生了重叠。
来看几个示例图:
注意最后一个例子,虽然 r1
和 r2
的边界没有交集,但由于 r1
完全包含在 r2
内部,因此仍属于“重叠”情况。
3. 初始结构设计
为了解决这个问题,我们首先需要定义一个矩形类。一个矩形可以由其左下角和右上角坐标唯一确定:
public class Rectangle {
private Point bottomLeft;
private Point topRight;
// 构造函数、getter/setter 省略
boolean isOverlapping(Rectangle other) {
...
}
}
其中 Point
是表示二维坐标点的类:
public class Point {
private int x;
private int y;
// 构造函数、getter/setter 省略
}
接下来我们会在 Rectangle
类中实现 .isOverlapping()
方法来判断当前矩形是否与另一个矩形重叠。
4. 解题思路
✅ 两个矩形不重叠的情况只有两种:
- 其中一个矩形完全位于另一个矩形的上方(即 y 轴方向无交集)
- 其中一个矩形完全位于另一个矩形的左侧(即 x 轴方向无交集)
如下图所示:
❌ 如果以上两个条件都不满足,则说明两个矩形必然有交集,即发生重叠。
我们可以手动画几个图验证这个逻辑。
5. Java 实现
基于上述分析,我们可以写出如下代码:
public boolean isOverlapping(Rectangle comparedRectangle) {
if (this.topRight.getY() < comparedRectangle.bottomLeft.getY() ||
this.bottomLeft.getY() > comparedRectangle.topRight.getY()) {
return false;
}
if (this.topRight.getX() < comparedRectangle.bottomLeft.getX() ||
this.bottomLeft.getX() > comparedRectangle.topRight.getX()) {
return false;
}
return true;
}
该方法会返回 false
如果其中一个矩形完全在另一个的上方或左侧,否则返回 true
表示重叠。
- 通过比较
y
坐标判断是否上下分离 - 通过比较
x
坐标判断是否左右分离
5.1. 不考虑边界的判断方式
在实际使用中,我们可能需要区分“边界是否算作重叠”。默认情况下,我们的 .isOverlapping()
方法是把矩形当作闭区间处理的,也就是说,只要边界接触就算重叠。
如果我们想忽略边界(即视为开区间),可以使用下面这个版本:
public boolean isOverlappingWithoutBorders(Rectangle comparedRectangle) {
if (this.topRight.getY() <= comparedRectangle.bottomLeft.getY() ||
this.bottomLeft.getY() >= comparedRectangle.topRight.getY()) {
return false;
}
if (this.topRight.getX() <= comparedRectangle.bottomLeft.getX() ||
this.bottomLeft.getX() >= comparedRectangle.topRight.getX()) {
return false;
}
return true;
}
测试代码如下:
Rectangle rectangle1 = new Rectangle(new Point(0, 0), new Point(5, 14));
Rectangle rectangle2 = new Rectangle(new Point(5, 0), new Point(17, 14));
assertTrue(rectangle1.isOverlapping(rectangle2)); // true: 边界接触视为重叠
assertFalse(rectangle1.isOverlappingWithoutBorders(rectangle2)); // false: 忽略边界则不重叠
两种方式都符合预期行为。
6. 总结
这篇文章介绍了如何通过坐标比较的方式判断两个矩形是否重叠,分别支持包含边界和不包含边界两种模式。这类算法在游戏开发、UI 布局、图形学等领域经常作为碰撞检测的基础策略使用。
完整源码可以在 GitHub 仓库 中找到。