【C#】点到线段最短距离的那条直线与线段的交点

/// <summary>
    ///  点到线段最短距离的那条直线与线段的交点,{x=...,y=...}
    /// </summary>
    /// <param name="x">线段外的点的x坐标</param>
    /// <param name="y">线段外的点的y坐标</param>
    /// <param name="x1">线段顶点1的x坐标</param>
    /// <param name="y1">线段顶点1的y坐标</param>
    /// <param name="x2">线段顶点2的x坐标</param>
    /// <param name="y2">线段顶点2的y坐标</param>
    /// <returns></returns>
    public Vector2 PointForPointToABLine(float x, float y, float x1, float y1, float x2, float y2)
    {
        Vector2 reVal = new Vector2();
        // 直线方程的两点式转换成一般式
        // A = Y2 - Y1
        // B = X1 - X2
        // C = X2*Y1 - X1*Y2
        float a1 = y2 - y1;
        float b1 = x1 - x2;
        float c1 = x2 * y1 - x1 * y2;
        float x3, y3;
        if (a1 == 0)
        {
            // 线段与x轴平行
            reVal = new Vector2(x, y1);
            x3 = x;
            y3 = y1;
        }
        else if (b1 == 0)
        {
            // 线段与y轴平行
            reVal = new Vector2(x1, y);
            x3 = x1;
            y3 = y;
        }
        else
        {
            // 普通线段
            float k1 = -a1 / b1;
            float k2 = -1 / k1;
            float a2 = k2;
            float b2 = -1;
            float c2 = y - k2 * x;
            // 直线一般式和二元一次方程的一般式转换
            // 直线的一般式为 Ax+By+C=0
            // 二元一次方程的一般式为 Ax+By=C
            c1 = -c1;
            c2 = -c2;

            // 二元一次方程求解(Ax+By=C)
            // a=a1,b=b1,c=c1,d=a2,e=b2,f=c2;
            // X=(ce-bf)/(ae-bd)
            // Y=(af-cd)/(ae-bd)
            x3 = (c1 * b2 - b1 * c2) / (a1 * b2 - b1 * a2);
            y3 = (a1 * c2 - c1 * a2) / (a1 * b2 - b1 * a2);
        }
        // 点(x3,y3)作为点(x,y)到(x1,y1)和(x2,y2)组成的直线距离最近的点,那(x3,y3)是否在(x1,y1)和(x2,y2)的线段之内(包含(x1,y1)和(x2,y2))
        if (((x3 > x1) != (x3 > x2) || x3 == x1 || x3 == x2) && ((y3 > y1) != (y3 > y2) || y3 == y1 || y3 == y2))
        {
            // (x3,y3)在线段上
            reVal = new Vector2(x3, y3);
        }
        else
        {
            // (x3,y3)在线段外
            float d1_quadratic = (x - x1) * (x - x1) + (y - y1) * (y - y1);
            float d2_quadratic = (x - x2) * (x - x2) + (y - y2) * (y - y2);
            if (d1_quadratic <= d2_quadratic)
            {
                reVal = new Vector2(x1, y1);
            }
            else
            {
                reVal = new Vector2(x2, y2);
            }
        }
        return reVal;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值