点在球体内当且仅当点到球心的平方距离不大于半径的平方;即计算dx=x−cx、dy=y−cy、dz=z−cz,判断dx²+dy²+dz²≤r²,避免开方以提升性能并减少浮点误差。

判断点是否在球体内的数学原理
核心是计算点到球心的距离,再与球半径比较。距离 ≤ 半径 → 点在球内(含表面)。不需要开方,直接用平方距离避免浮点误差和性能损耗。
std::sqrt 不必要,用距离平方更安全
常见错误是调用 std::sqrt 计算欧氏距离后再比较,既慢又引入额外浮点误差。正确做法是直接比对平方距离与半径平方。
- 设球心为
(cx, cy, cz),半径为r,待测点为(x, y, z) - 计算
dx = x - cx,dy = y - cy,dz = z - cz - 判断条件为:
dx*dx + dy*dy + dz*dz - 若需包含严格内部(不含表面),改用
而非 <code>
考虑浮点精度时的边界处理
当点非常接近球面(比如由数值积分或碰撞检测产生),r*r 和距离平方可能因舍入误差导致误判。可加入小量容差,但要注意容差值不能过大。
- 容差建议用
std::numeric_limits<double>::epsilon()</double>的倍数,例如1e-9(对double)或1e-5(对float) - 判断式改为:
dist_sq ,其中 <code>dist_sq是距离平方 - 注意:加容差只适用于“是否在球内或附近”这类宽松场景;物理引擎中常需确定性行为,此时应避免容差,改用一致的量化策略
封装成内联函数能兼顾清晰与性能
频繁调用时,定义一个 inline 辅助函数比重复写三行计算更可靠,也方便后续加日志或断言。
inline bool is_point_in_sphere(double x, double y, double z,
double cx, double cy, double cz,
double r) {
double dx = x - cx;
double dy = y - cy;
double dz = z - cz;
double dist_sq = dx*dx + dy*dy + dz*dz;
return dist_sq <p>如果使用 <code>glm::vec3</code> 或自定义向量类型,优先复用其 <code>length_squared()</code> 方法,而非手动展开分量。</p><p>球体退化为点(<code>r == 0</code>)时,该函数仍正确:仅当点与球心完全重合才返回 <code>true</code>。但若 <code>r ,逻辑失效——实际使用前应确保半径非负,或加断言 <code>assert(r >= 0)</code>。</code></p>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











