点是否在线段上

发布时间 2023-11-04 00:08:35作者: yanghui01

几种要考虑的情况

1) 点p和线段断点a, b重叠

2) pa, pb共线, p在线段ab上

3) pa, pb共线, p在线段ab外

4) pa, pb不共线

  

 

//点是否在线段上
public static bool IsPointOnSegment(Vector2 p, Vector2 a, Vector2 b)
{
    var pa = a - p;
    var pb = b - p;

    var cross = pa.x * pb.y - pa.y * pb.x; //pa×pb
    //叉乘结果如果为0, 说明平行或共线
    if (Mathf.Approximately(cross, 0))
    {
        //x,y方向都在线段端点范围内
        return (p.x - a.x) * (p.x - b.x) <= 0 && (p.y - a.y) * (p.y - b.y) <= 0;
    }
    return false;
}

 

能不能用点乘来判断共线?

是可以的,但是得把点和线段端点重叠的情况单独判断,因为重叠的时候,pa•ab结果为0,而上面4)中的图2,pa•ab结果也是0,没法区分这2种情况

//点是否在线段上
public static bool IsPointOnSegment2(Vector2 p, Vector2 a, Vector2 b)
{
    //点和线段端点重合时
    var pa = a - p;
    float paSqrLen = pa.sqrMagnitude;
    if (Mathf.Approximately(paSqrLen, 0))
        return true;

    var pb = b - p;
    float pbSqrLen = pb.sqrMagnitude;
    if (Mathf.Approximately(pbSqrLen, 0))
        return true;

    float dot = Vector2.Dot(pa, pb);
    if (Mathf.Approximately(dot, -1)) //p在线段上, pa和pb的夹角为180度, 即cos(180)=-1
        return true;

    //pa和pb的夹角为0度, 钝角, 90度, 锐角点情况
    return false;
}

 

 

参考

【数学基础】玩法常用几何计算汇总 - 知乎 (zhihu.com)

点是否在线段上 - 湫叶 - 博客园 (cnblogs.com)

【数学基础】玩法常用几何计算汇总 - 知乎 (zhihu.com),是否可以用点乘来判断的思考