aabb相交当且仅当在x、y、z三轴均重叠,即对每轴都满足max1 >= min2 && max2 >= min1;需先校验aabb合法性(min

判断AABB相交的核心逻辑是什么
两个AABB相交,当且仅当它们在x、y、z三个轴上都存在重叠。换句话说:只要有一个轴上不重叠,就一定不相交。这是AABB相交判定的数学本质,也是最高效的做法——无需计算交点、无需向量运算,纯坐标比较。
常见错误是试图用中心点距离或体积交集来判断,既慢又容易出错。正确做法是逐轴检查分离性:! (max1 等价于 <code>max1 >= min2 && max2 >= min1。
如何用C++写一个健壮的AABB相交函数
假设AABB用两个glm::vec3表示(min和max),或者自定义结构体。关键点在于:必须确保每个AABB自身的min确实小于等于max(即合法AABB),否则比较结果不可靠。
- 推荐直接写成内联函数,避免虚调用开销
- 使用
std::max/std::min不如直接比较,因为已知顺序;但若输入可能非法,需先校验 - 注意浮点精度:对float类型,建议用
std::abs(a - b) 代替<code>==,但相交判断中通常用>=/即可,不必额外加epsilon(除非坐标本身含显著误差)
示例:
bool intersect(const AABB& a, const AABB& b) {
return a.min.x <h3>如果AABB坐标是float,要注意什么</h3><p>浮点数本身不会导致逻辑错误,但若AABB由变换(如旋转后取轴对齐包围盒)生成,<code>min</code>/<code>max</code>可能因舍入误差出现<code>min > max</code>(哪怕只差一个ULP)。这种AABB是无效的,直接用于相交判断会返回错误结果。</p>
- 在构造AABB时应强制校正:
min = glm::min(v1, v2); max = glm::max(v1, v2); - 不要依赖用户传入的
min/max一定合法——尤其在多线程或跨模块传递时 - 调试时可加断言:
assert(a.min.x
性能差异:手写 vs glm::intersect
GLM库提供glm::intersect,但它针对OBB或射线设计,对AABB并不特化;其AABB版本内部仍是逐轴比较,但多了模板推导和参数转发开销。实测在热点路径(如BVH遍历)中,手写函数快10%~15%。
- 若项目已重度依赖GLM且无性能瓶颈,用
glm::intersect也完全可行 - 但若在每帧要调用数万次(如粒子碰撞粗筛),手写并
inline更稳妥 - 注意GLM的
glm::aabb不是标准类型,多数人还是用glm::vec3pair,此时glm::intersect不直接支持,得自己封装
真正容易被忽略的是AABB的有效性维护——它不在相交逻辑里,却决定结果是否可信。写完intersect函数后,顺手加个isValid()检查,比优化分支预测实在得多。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











