轴对齐包围盒(AABB)判断点是否在内只需检查点的x、y、z坐标是否均落在min_corner与max_corner对应维度的闭区间内;旋转长方体需先将点变换到局部坐标系再用AABB判断;GLM无直接contains函数,需手动实现,边界处理应根据需求选择闭包或开集并考虑浮点误差。

用 min 和 max 坐标做六面体轴对齐判断
轴对齐包围盒(AABB)是最常用、最高效的三维点-盒包含判断方式。它不依赖旋转,只看点的三个坐标是否全部落在盒的对应维度范围内。
假设长方体由两个对角顶点定义:min_corner = (x_min, y_min, z_min) 和 max_corner = (x_max, y_max, z_max)(注意:无需事先保证 x_min < x_max,但逻辑上应取实际最小/最大值)。判断点 p = (x, y, z) 是否在内,就是三组不等式同时成立:
if (x >= x_min && x <= x_max &&
y >= y_min && y <= y_max &&
z >= z_min && z <= z_max)实际写代码时,建议先归一化两个角点,避免传入顺序错误导致误判:
- 用
std::min/std::max对每维分别取极值,构造可靠的min_corner和max_corner - 若长方体是动态生成的(比如从点集计算),务必确保输入点已排序或做过极值提取
- 浮点比较时,如需容忍误差,改用
abs(x - x_mid) <= half_width + eps形式,而非直接边界比较
处理旋转长方体:必须转到局部坐标系再判断
一旦长方体绕任意轴旋转,AABB 判定就失效——点可能在世界坐标下“看起来”在盒内,实则穿出某个斜面。此时核心思路是:把点变换到长方体自身的局部坐标系(原点在中心、坐标轴沿长方体边方向),再用 AABB 方法判断。
立即学习“C++免费学习笔记(深入)”;
步骤简明如下:
- 获取长方体中心
center和三个正交单位轴向量u,v,w(通常来自旋转矩阵或四元数) - 计算局部坐标:
local_p = (p - center).dot(u), (p - center).dot(v), (p - center).dot(w) - 已知长方体半长宽高为
half_extents = (hx, hy, hz),则判定条件为:abs(local_x) <= hx && abs(local_y) <= hy && abs(local_z) <= hz
常见坑:轴向量没单位化、点减中心后没做点积投影、半尺寸用错(用了全长而非半长)。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
glm::intersect 不能直接用于点-盒包含判断
GLM 库里没有现成的 glm::contains(box, point) 函数。有人误用 glm::intersect 系列(如 glm::intersectRayAABB),但这些是为射线设计的,传入零长度射线会触发未定义行为或断言失败。
正确做法是自己写几行逻辑,或者封装一个工具函数:
bool contains(const glm::vec3& min_corner, const glm::vec3& max_corner, const glm::vec3& p) {
return (p.x >= min_corner.x && p.x <= max_corner.x &&
p.y >= min_corner.y && p.y <= max_corner.y &&
p.z >= min_corner.z && p.z <= max_corner.z);
}注意:GLM 的 vec3 支持成员访问(.x),无需额外索引;若用 std::array<float,3> 或自定义结构体,则需统一字段名或索引方式。
边界情况:点恰好落在面上/边上/顶点上算不算“内部”?
数学上,“位于长方体内”通常指闭包(即包含边界),所以等于任一边界坐标应返回 true。但某些物理引擎或碰撞系统要求严格内部(开集),此时需把 <= 改为 <,并注意浮点精度问题。
更稳健的做法是引入 epsilon,尤其当坐标来自计算而非用户输入时:
- 闭包含(含边界):
x >= x_min - eps && x <= x_max + eps - 开包含(不含边界):
x > x_min + eps && x < x_max - eps - eps 值取决于坐标量级,常用
1e-6f(单精度)或1e-9(双精度)
这个细节常被忽略,却直接影响碰撞响应是否触发、剔除是否漏点。

















