相交矩形的宽高等于x、y轴投影重叠长度,公式为max(0, min(r1.right, r2.right) - max(r1.left, r2.left))和max(0, min(b1,b2)-max(t1,t2)),需确保left≤right、top≤bottom,用std::max(0,...)截断负值防溢出与逻辑错误。

相交矩形的宽高计算原理
两个轴对齐矩形相交部分的宽度和高度,本质是求它们在 x 和 y 轴上投影的重叠长度。只要不相交,结果就是 0;否则,宽度 = min(r1.right, r2.right) - max(r1.left, r2.left),高度同理用 top/bottom 计算。
关键点在于:必须保证 left ≤ right、top ≤ bottom,否则直接返回 0 —— 很多手写结构体没做校验,导致负值参与后续计算出错。
C++ 中用 std::max 和 std::min 直接算
假设矩形用左上角 (x, y) 加宽高 w/h 表示(常见 SDL/Qt 风格),先转成 left/right/top/bottom 再算:
int left1 = x1, right1 = x1 + w1; int top1 = y1, bottom1 = y1 + h1; int left2 = x2, right2 = x2 + w2; int top2 = y2, bottom2 = y2 + h2; <p>int intersect_width = std::max(0, std::min(right1, right2) - std::max(left1, left2)); int intersect_height = std::max(0, std::min(bottom1, bottom2) - std::max(top1, top2));</p>
- 务必用
std::max(0, ...)截断负值,不能只靠条件判断后赋 0 —— 编译器对无分支写法更友好,且避免漏判 - 如果矩形坐标系 y 向下为正(如屏幕坐标),
top是较小值,bottom是较大值,公式不变;若 y 向上为正(如 OpenGL 纹理坐标),需确认 top/bottom 定义是否反转 - 整数运算下无需担心浮点误差,但注意溢出:当
right极大而left极小,right - left可能溢出 —— 实际中建议用long long中间计算或加范围检查
用 RECT 或自定义结构体时的常见坑
Windows 的 RECT 结构字段是 left/top/right/bottom,但 right 和 bottom 是“**不包含**”边界的(即右边界 = left + width,但 right 值本身不属矩形)。计算相交时公式依然成立,但如果你误把 right 当作“包含”,再额外减 1,就会少算 1 像素。
- 不要对
RECT做width = right - left + 1类推导后再套公式 —— 直接用原字段参与std::min/std::max即可 - 自定义结构体如
struct Rect { int x, y, w, h; };,必须明确文档说明坐标系和边界约定,否则和第三方库(如 OpenCV 的cv::Rect)混用时极易出错 -
cv::Rect的width/height是正数,area()返回w * h,但它的operator&已重载为交集,直接用(r1 & r2).width更安全
性能敏感场景下的优化提示
纯整数比较和减法没有分支,CPU 流水线友好。但如果在每帧调用数千次,仍可微优化:
- 避免重复计算:比如多个矩形与同一参考矩形求交,可提前算好参考矩形的
left/right等存为局部变量 - 用三元运算符替代
std::max在某些编译器下更快(但可读性略差):int w = (r1_right - SIMD 不适用——这是标量逻辑,强行向量化反而增加开销
真正容易被忽略的是坐标系一致性:同一个项目里混合使用 SDL 坐标(y 向下)、OpenGL 纹理坐标(y 向上)、数学绘图库(y 向上但 origin 在中心),会导致 top/bottom 含义颠倒,宽高计算结果全错。动手前先统一坐标系定义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











