如何在C、C#/.NET 2.0或Java中计算所有情况下点与线段之间的最短2D距离?

如何在C、C#/.NET 2.0或Java中计算所有情况下点与线段之间的最短2D距离?,c#,geometry,C#,Geometry,可能重复: 我正在寻找一种方法来计算所有情况下的最小距离。我发现解决方案存在以下问题: 带有图形概念图的解决方案显示的点始终与线段垂直,所以它位于“线段端点之间”。我的几何技能很糟糕,所以我无法验证这些解决方案在所有情况下都有效 算法解决方案是a:使用fortran或其他一些我不完全理解的语言, b:被人标记为不完整,c:调用未以任何方式描述的方法/函数(被认为是琐碎的) 2 a、b和c的好例子是 我将二维线段作为双类型坐标对(x1,y1),(x2,y2),将点作为双类型坐标对(x3,y3)

可能重复:

我正在寻找一种方法来计算所有情况下的最小距离。我发现解决方案存在以下问题:

  • 带有图形概念图的解决方案显示的点始终与线段垂直,所以它位于“线段端点之间”。我的几何技能很糟糕,所以我无法验证这些解决方案在所有情况下都有效

  • 算法解决方案是a:使用fortran或其他一些我不完全理解的语言, b:被人标记为不完整,c:调用未以任何方式描述的方法/函数(被认为是琐碎的)

  • 2 a、b和c的好例子是

    我将二维线段作为双类型坐标对(x1,y1),(x2,y2),将点作为双类型坐标对(x3,y3)。C#/Java/C解决方案都很受欢迎

    感谢您的回答&BR:Matti

    如果您有线路

    L:
    A*x+B*y+C=0

    那么从这条线到点
    (x1,y1)
    的距离是
    abs(A*x1+B*y1+C)/sqrt(A*A+B*B)
    。在您的情况下,如果您有间隔,
    (xa,ya);(xb,yb)
    你应该找到
    min(距离(x1,y1,xa,ya),距离(x1,y1,xb,yb))
    然后看看从
    (x1,y1)
    到L行的垂直距离是否在间隔上,那么答案是距离就是它。否则,两个距离的最小值。

    也回答了这个问题,因为它收集了所有语言的解决方案。答案也放在这里,因为这个问题特别要求C#解决方案。此项修改自:


    我在这里统计了6种不同语言的实现:@oded:你指的是哪一部分?它被询问和回答了数百万次?或者一开始就没有“如何计算”?正如我所说,我为糟糕的搜索技巧道歉,但如果一个人无法想象一开始的“如何计算”。。。好。你的链接是帮助人们互相理解。我想你完全理解我了。@tim:非常感谢!你是a。没有正确描述你的问题。B没有向我们展示你迄今为止所做的尝试。C没有解释你在哪里遇到困难。缺少“如何…”似乎是个问题。我一点也没想到,但我以后会问更好的问题。呃,哪一点A、B、C是直线终点,哪一点是实际的奇点?你真的应该正确地命名变量,这就是为什么我们使用名称而不是数字。它在注释中。A和B是直线或线段的顶点,C是讨论中的点。一旦你知道了这一点,单字母变量名称就更容易阅读了。第一个函数的注释是
    //计算点积AB。AC
    ,但它似乎是在计算点AB•BC。这是打字错误,还是我没有完全理解点积?这是给NaN一条垂直线和共线点//计算点积AB。交流电。。。应该是公元前AB年吗?
    //Compute the dot product AB . BC
    private double DotProduct(double[] pointA, double[] pointB, double[] pointC)
    {
        double[] AB = new double[2];
        double[] BC = new double[2];
        AB[0] = pointB[0] - pointA[0];
        AB[1] = pointB[1] - pointA[1];
        BC[0] = pointC[0] - pointB[0];
        BC[1] = pointC[1] - pointB[1];
        double dot = AB[0] * BC[0] + AB[1] * BC[1];
    
        return dot;
    }
    
    //Compute the cross product AB x AC
    private double CrossProduct(double[] pointA, double[] pointB, double[] pointC)
    {
        double[] AB = new double[2];
        double[] AC = new double[2];
        AB[0] = pointB[0] - pointA[0];
        AB[1] = pointB[1] - pointA[1];
        AC[0] = pointC[0] - pointA[0];
        AC[1] = pointC[1] - pointA[1];
        double cross = AB[0] * AC[1] - AB[1] * AC[0];
    
        return cross;
    }
    
    //Compute the distance from A to B
    double Distance(double[] pointA, double[] pointB)
    {
        double d1 = pointA[0] - pointB[0];
        double d2 = pointA[1] - pointB[1];
    
        return Math.Sqrt(d1 * d1 + d2 * d2);
    }
    
    //Compute the distance from AB to C
    //if isSegment is true, AB is a segment, not a line.
    double LineToPointDistance2D(double[] pointA, double[] pointB, double[] pointC, 
        bool isSegment)
    {
        double dist = CrossProduct(pointA, pointB, pointC) / Distance(pointA, pointB);
        if (isSegment)
        {
            double dot1 = DotProduct(pointA, pointB, pointC);
            if (dot1 > 0) 
                return Distance(pointB, pointC);
    
            double dot2 = DotProduct(pointB, pointA, pointC);
            if (dot2 > 0) 
                return Distance(pointA, pointC);
        }
        return Math.Abs(dist);
    }