Как рассчитать кратчайшее расстояние 2D между точкой и отрезком во всех случаях в C, C# / .NET 2.0 или Java?
Возможный дубликат:
Наименьшее расстояние между точкой и отрезком
Я ищу способ рассчитать минимальное расстояние во всех случаях. проблемы с решениями, которые я нашел:
Решения с графическими концептуальными чертежами показывают точку всегда перпендикулярно отрезку, поэтому она находится "между конечными точками отрезка". Мои навыки геометрии ужасны, поэтому я не могу убедиться, что эти решения работают во всех случаях.
Алгоритмические решения: а: с фортраном или другим языком, который я не до конца понимаю, б: помечены людьми как неполные, в: вызов методов / функций, которые никоим образом не описаны (считаются тривиальными).
Хороший пример 2 а, б и в
Наименьшее расстояние между точкой и отрезком
у меня есть двухмерный отрезок в виде пары координат двойного типа (x1, y1), (x2,y2) и точка в качестве координаты двойного типа (x3,y3). Решения C#/Java/C приветствуются.
Спасибо за ваши ответы и BR: Матти
2 ответа
Ответил также наименьшее расстояние между точкой и отрезком, потому что это собирает решения на всех языках. Ответ поставлен также здесь, потому что этот вопрос задает конкретно решение C#. Это изменено с http://www.topcoder.com/tc?d1=tutorials&d2=geometry1&module=Static:
//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);
}
Если у вас есть линия
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( distance(x1, y1, xa, ya), distance(x1, y1, xb, yb))
тогда посмотрим, если перпендикулярно от (x1, y1)
чтобы линия L была на интервале, тогда ответ - это расстояние. в противном случае мин двух расстояний.