矩形并集是覆盖两个轴对齐矩形的最小包围盒,其左、上、右、下边界分别为两矩形对应边界的min(a.x1,b.x1)、min(a.y1,b.y1)、max(a.x2,b.x2)、max(a.y2,b.y2)。

什么是矩形并集?先看坐标定义
C++里没有内置的“矩形并集”运算,得自己算。核心前提是:两个轴对齐矩形(即边平行于坐标轴),用左上角 (x1, y1) 和右下角 (x2, y2) 表示(常见于 OpenCV、Qt、SDL 等库)。并集不是面积相加,而是能覆盖两个矩形的最小矩形——也就是它们的包围盒。
关键判断逻辑是:
- 并集左边界 =
min(r1.x1, r2.x1) - 并集上边界 =
min(r1.y1, r2.y1) - 并集右边界 =
max(r1.x2, r2.x2) - 并集下边界 =
max(r1.y2, r2.y2)
注意:这里假设 y 轴向下增长(如 OpenCV 坐标系);若 y 向上增长(如数学坐标系),上/下边界逻辑不变,但语义上“上”对应更小的 y 值,所以仍用 min 取顶部。
用 std::min/max 直接计算,别手写 if
C++ 标准库的 std::min 和 std::max 支持多个参数或 initializer_list,写起来干净且无分支预测开销:
struct Rect {
double x1, y1, x2, y2; // 左上、右下
};
<p>Rect union_rect(const Rect& a, const Rect& b) {
return {
std::min(a.x1, b.x1),
std::min(a.y1, b.y1),
std::max(a.x2, b.x2),
std::max(a.y2, b.y2)
};
}</p>
常见错误:
- 混淆顶底:把
y1当作底部,导致并集上下颠倒 - 忘记检查空矩形:如果输入矩形本身无效(
x1 >= x2或y1 >= y2),并集结果也会无效;建议在调用前做valid()判断,或让union_rect内部返回规范化矩形(见下一条)
处理无效矩形:空集与规范化
两个矩形可能完全不相交,但并集依然有定义(只要各自有效)。真正要警惕的是输入本身就是空矩形(比如 x1 == x2 或负宽高):
- 若任一输入矩形为空(
x1 >= x2 || y1 >= y2),直接返回另一个(或按需返回空) - 更稳妥的做法是返回「规范化」矩形:确保
x1 ,否则设为 <code>{0,0,0,0}或抛异常
bool is_valid(const Rect& r) {
return r.x1 Rect normalize(const Rect& r) {
return {std::min(r.x1, r.x2), std::min(r.y1, r.y2),
std::max(r.x1, r.x2), std::max(r.y1, r.y2)};
}
很多库(如 OpenCV 的 cv::Rect)构造时会自动 normalize;自己实现时容易漏掉这点,导致后续面积计算为负。
和交集、面积一起用才真正实用
单独算并集意义有限,通常配合交集(intersection)判断是否相交,或计算并集面积用于 IoU(交并比):
- 并集面积 =
(union_rect.x2 - union_rect.x1) * (union_rect.y2 - union_rect.y1) - 交集矩形:左=
max(a.x1,b.x1),上=max(a.y1,b.y1),右=min(a.x2,b.x2),下=min(a.y2,b.y2) - 若交集右≤左 或 下≤上 → 无交集,交集面积为 0
IoU 计算中,并集面积必须是「两个矩形覆盖的总像素数」,不能简单加面积再减交集(因为浮点误差或 sub-pixel 边界可能导致微小偏差),所以老老实实算一次并集矩形再求面积更可靠。
坐标类型选 float 还是 double?取决于精度需求;图像处理常用 int(像素级),但做仿射变换后要用浮点。类型不一致时,std::min 会隐式转换,可能截断——显式 cast 更安全。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











