S01E17:点在球体表面的投影点/最近点

1,113 阅读1分钟

说明

点在球体表面的投影点,其实就是点与球心连线,与球体表面的交点,这一点也是点到球体的最近点。

几何

那么这个交点如何计算呢?其实很简单,我们将这个点和球心组成向量,只要将点 C 沿着向量 CA 方向移动一段距离就可以了,而这个距离就是点到球体表面的距离,

但是,沿着向量 CA 方向移动一段距离,这个操作不仅要求 CA 的长度,还需要再将向量 CA 归一化,再乘以距离,我们应尽量避免过多的归一化,以提高计算效率和精度。

所以,我们可以把向量反过来,计算出球体半径与向量 AC 长度的比值(比如30%),然后将球心沿向量 AC 移动 30% 就好了。这样可以相对简单一点儿(其实也没简单多少)。

这个计算过程,对于点在球体内部,也是适用的。但是当点与球心重合时,最近点、投影点无法定义。

代码

static func projectionOnSphere(from point:simd_float3, to sphere:Sphere) -> simd_float3? {
    let vector = point - sphere.position
    let length = simd_length(vector)
    if length < Float.leastNormalMagnitude {
        // 点与球心重合,未定义
        return nil
    }
    let factor = sphere.radius / length
    let target = sphere.position + factor * vector
    
    return target
}