给定线段 s→e 与点 p,返回点到线段的最短距离;并给出“线段-线段”最近距离的典型扩展思路与边界处理。

Returns the shortest distance between point p and the line segment from point s to e. Usage: Point a, b(2,2), p(1,1); bool onSegment = segDist(a,b,p) < 1e-10; Status: tested

展开阐述

  • 定义与背景

    • 对象:二维点/向量 P(常用 double/long long,见 039-几何-点),线段由端点 s,e 表示。
    • 目标:最短距离 d = min_{t∈[0,1]} | s + t(e−s) − p |,对应“投影裁剪”的标准模型。
    • 适用:最近点查询、点在段上判定的几何阈值(与 038-几何-点在线段上 协同)、碰撞检测的最短分离向量求解。
  • 接口/数据结构(据实现)

    • 函数签名:template double segDist(P& s, P& e, P& p)
      • s,e:线段端点;p:查询点
      • 返回:最短距离(double)
    • 类型注意:当 P=Point 时,内部涉及点积/模长平方等“三坐标乘积/平方和”,大坐标可能溢出;建议以 long double 计算中间量。
  • 核心流程/要点(向量投影 + 区间裁剪)

    1. 退化判定
      • 若 s==e:线段退化为点,直接返回 |p−s|
    2. 投影参数
      • 设 v = e−s,d = |v|²
      • 原始参数 τ = (p−s)·v
      • 裁剪 t = clamp(τ, 0, d)
    3. 最近点与距离
      • 最近点 q = s + v·(t/d)
      • 返回 |p−q|
    4. 与“点在线段上”关系
  • 复杂度与边界条件

    • 时间复杂度:O(1)
    • 边界/退化:
      • s==e:直接点距
      • 极短线段:|v|²≈0 时需以 eps 判零避免数值爆炸
    • 数值与溢出:
      • 整型:dot(v, w) 与 |v|² 可能超 64 位;可改用 128 位中间值或切换到长浮点
      • 浮点:统一 eps(如 1e−9)用于“在段上/端点吸附”的阈值判断
  • 扩展:线段-线段最近距离(典型方案)

    • 思路:设两段 s1–e1、s2–e2
      1. 若两段相交(见 048-几何-线段相交),距离为 0
      2. 否则,取四种候选:
        • 点 s1 到段 s2–e2 的 segDist
        • 点 e1 到段 s2–e2 的 segDist
        • 点 s2 到段 s1–e1 的 segDist
        • 点 e2 到段 s1–e1 的 segDist
      3. 取四者最小值即为段段最近距离
    • 说明:该模式内隐地完成了“对端点投影后落段内则取垂距,否则取端点距”的全覆盖分类
  • 变体/协同

    • 点到射线距离:将 t 裁剪到 [0, +∞)
    • 032-几何-点线距离 协同:共享“分子/分母”(有向面积与 |v|),可缓存以降常数
    • 035-几何-线的投影与反射 协同:若还需最近点坐标 q,可直接返回投影点作为下游输入
  • 正确性要点与不变式

    • 投影裁剪:在仿射参数域 [0,1] 上取最优,保证覆盖“端点-垂足-端点”的三类情形且彼此无遗漏
    • 方向一致性:所有向量以差向量构造,避免坐标原点依赖
  • 与相邻技术的对比与取舍

    • 与枚举端点距离相比:加入投影裁剪后可在线段内部得到垂距(更短)
    • 与显式解二次函数相比:向量法更短且稳定,与其他几何原语可复用

关联节点