本文详解如何用纯 java 逻辑(不依赖 math 类)准确计算两个轴对齐矩形的交集面积与并集面积,并修复常见边界判断错误,提供可直接运行的完整实现。
本文详解如何用纯 java 逻辑(不依赖 math 类)准确计算两个轴对齐矩形的交集面积与并集面积,并修复常见边界判断错误,提供可直接运行的完整实现。
在二维平面中,给定两个以左上角为基准、宽高非负的轴对齐矩形(即边平行于坐标轴),其并集面积 = 矩形 R1 面积 + 矩形 R2 面积 − 二者交集面积。关键难点在于鲁棒地计算交集区域的宽度与高度——必须正确处理所有相对位置关系(完全分离、部分重叠、完全包含等),且不能使用 Math.max/min 等工具类方法。
✅ 正确的重叠区域计算逻辑
交集存在的充要条件是:x 方向有重叠 ∧ y 方向有重叠。
- x 方向重叠宽度 = max(0, min(R1.right, R2.right) − max(R1.left, R2.left))
- y 方向重叠高度 = max(0, min(R1.bottom, R2.bottom) − max(R1.top, R2.top))
但由于题目禁止使用 Math 类,我们需用条件表达式手动实现等价逻辑:
- R1 左边界:x1,右边界:x1 + w1
- R2 左边界:x2,右边界:x2 + w2
- x 重叠宽度 = max(0, min(x1+w1, x2+w2) − max(x1, x2)) → 拆解为:
int left = (x1 < x2) ? x2 : x1; // 两矩形左边界中的较大者(交集左边界) int right = ((x1 + w1) < (x2 + w2)) ? (x1 + w1) : (x2 + w2); // 两矩形右边界中的较小者(交集右边界) int overlapX = (right > left) ? (right - left) : 0;
同理处理 y 方向(注意:题目约定 (x,y) 为左上角,y 轴向下增长,因此上边界为 y,下边界为 y + h):
立即学习“Java免费学习笔记(深入)”;
int top = (y1 < y2) ? y2 : y1; // 交集上边界(y 值更大者更靠下?错!注意:y 值小才更靠上) // ⚠️ 关键修正:因 y 轴向下为正,"上边界" 对应更小的 y 值,"下边界" 对应更大的 y 值 // 所以交集的上边界 = max(y1, y2) ❌ → 实际应为:max(y1, y2) 是更靠下的边,而交集的上边界应取「更靠上的边」= min(y1, y2) // 但交集的垂直范围由「更靠下的上边界」和「更靠上的下边界」决定 —— 正确逻辑如下: int upper = (y1 < y2) ? y1 : y2; // 更靠上的上边界(y 值更小) int lower = ((y1 + h1) < (y2 + h2)) ? (y1 + h1) : (y2 + h2); // 更靠下的下边界(y 值更大) int overlapY = (lower > upper) ? (lower - upper) : 0;
✅ 更清晰、无歧义的写法(推荐):
// x 重叠 int xLeft = Math.max(x1, x2); // ← 但题目禁用 Math,故改用三元 int xRight = Math.min(x1 + w1, x2 + w2); // 替代实现(无 Math): int xLeftSafe = (x1 > x2) ? x1 : x2; int xRightSafe = ((x1 + w1) < (x2 + w2)) ? (x1 + w1) : (x2 + w2); int overlapX = (xRightSafe > xLeftSafe) ? (xRightSafe - xLeftSafe) : 0; // y 重叠(注意:y 向下增长,上边 y 小,下边 y+h 大) int yTop = (y1 < y2) ? y1 : y2; // 更靠上的上边界(y 值更小) int yBottom = ((y1 + h1) < (y2 + h2)) ? (y1 + h1) : (y2 + h2); // 更靠下的下边界(y 值更大) int overlapY = (yBottom > yTop) ? (yBottom - yTop) : 0;
? 完整可运行代码(含输入解析与清晰输出)
import java.util.Scanner;
public class UnionRectangleCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("- What is the area of the union of two rectangles R1 and R2, where top left corner of R1 is (X1,Y1) and its size is (W1,H1), and top left corner of R2 is (X2,Y2) and its size is (W2,H2)?\n");
System.out.print("Please enter X1, Y1, W1, H1, X2, Y2, W2, H2: ");
int x1 = sc.nextInt();
int y1 = sc.nextInt();
int w1 = sc.nextInt();
int h1 = sc.nextInt();
int x2 = sc.nextInt();
int y2 = sc.nextInt();
int w2 = sc.nextInt();
int h2 = sc.nextInt();
int area1 = w1 * h1;
int area2 = w2 * h2;
int intersectionArea = calculateIntersectionArea(x1, y1, w1, h1, x2, y2, w2, h2);
int unionArea = area1 + area2 - intersectionArea;
System.out.println("Result: Intersection area is " + intersectionArea + " thus the total area of the union is " + unionArea + ".");
sc.close();
}
public static int calculateIntersectionArea(int x1, int y1, int w1, int h1,
int x2, int y2, int w2, int h2) {
// Compute overlapping width on x-axis
int xLeft = (x1 > x2) ? x1 : x2; // rightmost left edge
int xRight = ((x1 + w1) < (x2 + w2)) ? (x1 + w1) : (x2 + w2); // leftmost right edge
int overlapX = (xRight > xLeft) ? (xRight - xLeft) : 0;
// Compute overlapping height on y-axis
// Since (x,y) is top-left and y increases downward:
// top boundary = smaller y; bottom boundary = larger y (i.e., y + h)
int yTop = (y1 < y2) ? y1 : y2; // uppermost top edge
int yBottom = ((y1 + h1) < (y2 + h2)) ? (y1 + h1) : (y2 + h2); // lowermost bottom edge
int overlapY = (yBottom > yTop) ? (yBottom - yTop) : 0;
return overlapX * overlapY;
}
}⚠️ 常见错误与注意事项
- 坐标系理解错误:本题采用屏幕坐标系(y 向下为正),因此矩形“高度”向下延伸,y + h 是底边纵坐标,而非 y - h。
- 重叠判定遗漏:若仅判断 x1 < x2 + w2 && x2 < x1 + w1 等,虽数学等价,但易在边界相切(overlap=0)时出错;显式计算 left/right 并比较更安全。
- 负尺寸未校验:题目隐含 w1,w2,h1,h2 ≥ 0,实际应用中建议前置校验。
- 整数溢出风险:大坐标或大尺寸可能导致 x1+w1 溢出,生产环境应使用 long 或校验。
- 原代码致命缺陷:overLapArea = Area - w1 * x2; 属于笔误,完全无关,已彻底移除。
✅ 验证示例
输入:0 0 5 10 0 0 10 5
- R1:(0,0) 宽5高10 → 覆盖 [0,5) × [0,10)
- R2:(0,0) 宽10高5 → 覆盖 [0,10) × [0,5)
- 交集:[0,5) × [0,5) → 面积 = 5×5 = 25
- 并集:50 + 50 − 25 = 75 ✔️
掌握此逻辑后,可轻松扩展至多矩形并集(如扫描线算法)或带浮点坐标的版本。核心始终是:分离 x/y 一维重叠计算,再组合为二维交集面积。










