S01E09:直线与直线间的距离

542 阅读1分钟

说明

直线与直线间的距离,就是同时垂直于两条直线的线段的长度。

几何

那么,如何得到同时垂直于两条直线的向量呢?当然是叉乘!首先,我们有空间中的两条直线 AB 和 CD:

利用叉乘,就得到了即垂直于 AB,又垂直于 CD 的向量: 为了更方便看清,我构造了一条与直线 AB 同方向的向量:CC'

接下来,连接两条直线上的点,得到向量 AC,再将其投影到垂线 CE 上,就得到了直线间的距离。

需要注意的是,如果两条直线平行,那么叉乘结果为 0,我们直接求直线 AB 上任意一点到 CD 的距离就可以了。

代码

static func distanceBetween(line1:Line, line2:Line) -> Float {
    let crossValue = cross(line2.direction, line1.direction)
    let vector = line1.position - line2.position
    if length_squared(crossValue) < 0.0001 {
        // 平行
        return distanceBetween(point:line1.position, line:line2)
    }
    let distanceVector = normalize(crossValue)
    // 可能是正的,也可能是负的
    let dis = dot(distanceVector, vector)
    
    return abs(dis)
}

正方向

因为叉乘是右手法则:AB x CD 代表,右手手指从 AB 方向,转到 CD 方向,大姆指方向为正。

而直线不仅有方向,还有位置,比如直线 EE'与 AB 同方向,但不同位置,它们与向量 CD 的叉乘结果都是 CE,但是 EE'到 CD 的向量 EC,显示与 CE 是相反的,也就是投影会得到负值:

所以,我们最后求得的投影距离,需要再求绝对值。