说明
点到直线的最近点,其实就是垂足。但是点到射线的最近点坐标,并不一定是垂足,这取决于点的位置。
几何
射线由一个点和一个向量组成,再与另外的点,可自然组成一个平面。因此,三维中的点到射线的最近点,可以直接转换到二维平面上来理解。
如下图,当点 C 在射线 AB 的正方向时,点到射线的最近点,其实就是点 C 到 AB 所在直线的最近点:
而当点 D 和点 E 在射线 AB 的负方向时,那么最近点就应该是射线的原点 A:
那么如何确定点在正方向还是负方向呢?我们可以使用点乘。构造一个从 A 指向点 D 的向量,与射线方向 AB 向量,进行点乘。当点乘结果大于 0 时,说明在正方向;小于 0 时,说明在负方向。
代码
/// 定义射线结构体
struct Ray {
let position:simd_float3
let direction:simd_float3
}
///点到射线的最近点坐标
static func nearestPointOnRay(from point:simd_float3, to ray:Ray) -> simd_float3 {
let vector = point - ray.position
let normalizedDirection = normalize(ray.direction)
let dotValue = dot(vector, normalizedDirection)
if dotValue <= 0 {
return ray.position
}
let tarPoint = ray.position + dotValue * normalizedDirection
return tarPoint
}
项目代码
本系列文章代码已发布在 github:ComputationalGeometrySwift