如何在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*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);
}