aabb碰撞判定应使用分离轴思想:仅需检查x、y轴投影是否重叠,任一轴分离即无碰撞;推荐用min_x/max_x命名并以

两个AABB矩形不发生碰撞,当且仅当它们在x轴或y轴上完全分离;反过来,只要x轴重叠且y轴也重叠,就一定碰撞。
为什么用“分离轴”而不是“求交”来判断
AABB是轴对齐的,没有旋转,所以只需检查两个方向:x轴投影是否重叠、y轴投影是否重叠。只要任一方向不重叠(比如rect1.right ),就可立即返回<code>false,无需计算交集区域——这比构造交集再判空快得多,也更安全(避免浮点误差下交集面积为负却未被察觉)。
常见错误是写成if (overlap_x && overlap_y) return true;但漏掉对坐标顺序的假设:必须确保每个矩形的left 、<code>bottom ,否则比较结果会翻转。
实操建议:
- 统一用
min_x/max_x代替left/right,显式表达区间端点语义 - 构造矩形时强制校验:
std::min(x1, x2)和std::max(x1, x2)初始化边界 - 若输入来自用户拖拽或传感器,务必先归一化:调用
normalize()函数交换错位端点
std::abs和std::max不能直接用于AABB碰撞判定
有人尝试用中心点距离判断:abs(center1.x - center2.x) ,这看似简洁,但实际引入了冗余计算和精度风险:浮点减法+绝对值+加法,三步都可能累积误差;更重要的是,它隐含假设矩形对称,而AABB本身只定义边界,不依赖中心。
更糟的是用std::max(left1, left2) 这类写法——逻辑正确,但可读性差,且容易把<code>max和min参数顺序写反(比如误写成std::max(right1, right2))。
推荐写法(清晰、易测、难出错):
bool intersects(const AABB& a, const AABB& b) {
if (a.max_x <p>注意用<code>而非<code>:边界刚好相切(如<code>a.max_x == b.min_x</code>)算碰撞,这是绝大多数物理引擎和UI系统的约定。</code></code></p><h3>处理浮点坐标的边界陷阱</h3><p>当矩形坐标是<code>float</code>或<code>double</code>时,<code>a.max_x == b.min_x</code>可能因舍入误差无法精确成立。此时严格相等判断会漏判“本应相切”的情况。</p><p>解决方案不是加epsilon暴力比较(那会扩大碰撞判定范围,引发误触),而是从设计上规避:如果业务允许,把坐标全转为整数像素(<code>int</code>)处理;若必须用浮点,则在归一化阶段做一次“安全收缩”:</p><pre class="brush:php;toolbar:false;">// 归一化时微调,防止因计算误差导致 max <p>关键点:epsilon只用于修复自身计算误差,绝不用于跨矩形比较;所有碰撞主逻辑仍用原始<code>判断。</code></p><p>真正容易被忽略的,是矩形数据来源是否可信——比如从JSON解析出的<code>"left": 100.0000001</code>和<code>"right": 99.9999999</code>,这种倒置必须在构造<code>AABB</code>对象时拦截,而不是等到<code>intersects()</code>里才发现逻辑崩坏。</p>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











