如何在2D空间中按指定向量方向计算点到线段的距离?
TypeScript实现点到线段沿指定方向的距离计算
核心逻辑
先建立过目标点、沿指定方向的直线参数方程,再联立线段的参数方程求解交点,最后根据交点是否在线段范围内、是否沿指定方向返回结果。
代码实现
type Point = { x: number; z: number }; function distanceAlongVectorToSegment( point: Point, segmentStart: Point, segmentEnd: Point, direction: Point ): number | undefined { // 计算线段的方向向量 const segDx = segmentEnd.x - segmentStart.x; const segDz = segmentEnd.z - segmentStart.z; // 计算行列式,判断直线与线段是否平行 const determinant = direction.z * segDx - direction.x * segDz; // 处理平行/共线情况 if (Math.abs(determinant) < 1e-9) { // 检查点与线段是否共线 const crossProduct = (point.x - segmentStart.x) * segDz - (point.z - segmentStart.z) * segDx; if (Math.abs(crossProduct) > 1e-9) { // 不共线,无交点 return undefined; } // 共线时,计算线段两端点在方向直线上的参数t const tStart = (segmentStart.x - point.x) * direction.x + (segmentStart.z - point.z) * direction.z; const tEnd = (segmentEnd.x - point.x) * direction.x + (segmentEnd.z - point.z) * direction.z; // 筛选沿指定方向的有效t值(t≥0,允许微小精度误差) const validTs = [tStart, tEnd].filter(t => t >= -1e-9); if (validTs.length === 0) return undefined; // 返回最近的有效距离(最小的非负t) const minValidT = Math.min(...validTs); return minValidT >= 0 ? minValidT : undefined; } // 非平行情况,求解参数t和s const e = segmentStart.x - point.x; const f = segmentStart.z - point.z; const t = (e * (-segDz) - (-segDx) * f) / determinant; const s = (direction.x * f - e * direction.z) / determinant; // 检查交点是否在线段上(s∈[0,1],允许微小精度误差),且沿指定方向(t≥0) if (s >= -1e-9 && s <= 1 + 1e-9 && t >= -1e-9) { return t; // 方向向量已归一化,t即为距离 } // 无有效交点 return undefined; }
关键说明
- 参数
t的意义:因为输入的direction是归一化向量,t的数值就是从起点到交点的距离(t≥0表示沿指定方向,t<0表示反方向) - 浮点数精度:用
1e-9作为误差阈值,避免因浮点运算精度问题导致的错误判断 - 共线处理:当直线与线段共线时,筛选出沿指定方向的线段端点或线段上的点,返回最近的距离
内容的提问来源于stack exchange,提问作者Raza_Loba
相关产品推荐
相关产品推荐

