Нахождение кратчайшего расстояния между точкой и отрезком - PullRequest
0 голосов
/ 23 сентября 2018

Мне нужно найти кратчайшее расстояние между точкой и отрезком (точка определена как xy, линия определена с использованием конечных точек ax ay и bx by).

Я написал некоторый код, но он неКажется, работает для некоторых параметров.Я не уверен, есть ли где-то небольшая ошибка или (более вероятно), как она работает, в корне неверно.

public static double GetDist(double ax, double ay, double bx, double by, double x, double y)
{
    double Perpendicular = Math.Abs((by - ay) * x - (bx - ax) * y + bx * ay - by * ax) /
                           Math.Sqrt((ay - by) * (ay - by) + (ax - bx) * (ax - bx));
    double to_axay = Math.Sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay));
    double to_bxby = Math.Sqrt((x - bx) * (x - bx) + (y - by) * (y - by));

    double dist1 = Math.Sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay));
    double dist2 = Math.Sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay));

    double theta1 = Math.Atan(dist1);
    double theta2 = Math.Atan(dist2);

    double angle = Math.Abs(theta2 - theta1);

    if (angle > Math.PI)
        angle = 2 * Math.PI - angle;

    if (angle <= (1 / 2 * Math.PI))
        return Perpendicular;
    else
    {
        if (to_axay >= to_bxby)
            return to_bxby;
        else
            return to_axay;
    }
}

Пример, когда она не работает:

x =0, y = 30

ax = -30, ay = 0

bx = 30, при = 0

Ожидаемый результат - 30. Моя программа вместо этого возвращает 42.4264.

1 Ответ

0 голосов
/ 23 сентября 2018

У вас есть ошибка в угловой части, поэтому результат рассчитывается для одного из концов (30 * sqrt (2)).(Обратите внимание, что вы рассчитываете atan для расстояния, но аргумент должен быть отношением двух расстояний. Кроме того, такой подход страдает проблемами с диапазоном atan и т. Д.).

Но вам не нужно делать тригонометрические вычисления.Просто найдите скалярное произведение векторов ba и bp и скалярное произведение векторов ab и ap .

Если первый отрицателен (угол abp тупой), найдите расстояние до конца b .Если второй отрицательный, получить расстояние до конца a .

Если оба значения отрицательны, используйте расстояние, рассчитанное по перекрестному произведению (оно у вас уже есть).Обратите внимание, что последнее расстояние может быть вычислено после всех сравнений.

Проверенный код :

public static double GetDist(double ax, double ay, double bx, 
                             double by, double x, double y)  {
   if ((ax-bx)*(x-bx)+(ay-by)*(y-by) <= 0)
      return Math.Sqrt((x - bx) * (x - bx) + (y - by) * (y - by));

   if ((bx-ax)*(x-ax)+(by-ay)*(y-ay) <= 0)
      return Math.Sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay));

 return Math.Abs((by - ay)*x - (bx - ax)*y + bx*ay - by*ax) /
     Math.Sqrt((ay - by) * (ay - by) + (ax - bx) * (ax - bx));
}

    public static void Main()
    {
        Console.WriteLine(GetDist(0, 2, 2, 0, 0, 0));
        Console.WriteLine(GetDist(0, 2, 2, 0, 0, 3));
    }



1.41421356237309
1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...