Расстояние от точки до линии на Земле - PullRequest
3 голосов

Ответы [ 6 ]

8 голосов
/ 18 октября 2011

Начнем с некоторых предположений:

Итак, перефразируя ваш вопрос:

Учитывая три точки земной поверхности - p0, p1 и p2, найдите точку земной поверхности на малой дуге большой окружности, определенной p1 и p2, котораяявляется ближайшим к p0.

В качестве инфраструктуры для решения нам потребуется:

  • Точная функция, которая находит целевую точку на основе начальной точки,начальный азимут и расстояние.
  • Точная функция, которая измеряет расстояние между двумя точками.

Я предлагаю использовать Прямые и обратные функции GeographicLib соответственно, которыесамые точные реализации, которые я знаю.

С тех пор математикаучастие в вычислениях сплюснутых сфероидов очень нелинейно, мы построим итеративное решение.

В качестве первого шага мы попытаемся понять, как граф, где ось X является точкой на малой дугебольшой круг, определенный p1 и p2, а ось Y - это расстояние от p0 до этой точки - может выглядеть следующим образом:

Существует несколько вариантов того, как может выглядеть такой график: функция может монотонно увеличиваться илимонотонно убывающийОн также может содержать одну точку, где его 1-я производная может быть 0. Это могут быть минимумы (довольно тривиальные), но это также могут быть и максимумы (например, если Lat (p0) = 0, Lat (p1) =100 и Lat (p2) = - 100).Однако во всех случаях есть 0 или 1 точка, где производная меняет знак.

Поняв это, теперь мы можем построить итерационный алгоритм.В каждой итерации:

Мы будем вычислять dist (p0, p1), dist (p0, p2), а также dist (p0, pM), где M - средняя точка между p1 и p2 на минорнойдуга большого круга, определяемого p1 и p2.Сейчас.мы проверим:

  • if (dist (p0, p1) <= dist (p0, pM)) && (dist (p0, pM) <= dist (p0, p2)) - p0ближе к p1, чем к p2 </li>
  • , если (dist (p0, p2) <= dist (p0, pM)) && (dist (p0, pM) <= dist (p0, p1)) -p0 ближе к p2, чем к p1 </li>
  • , если (dist (p0, p1) <= dist (p0, p2)) && (dist (p0, p2) <= dist (p0, pM))- p0 равно p1 </li>
  • if (dist (p0, p2) <= dist (p0, p1)) && (dist (p0, p1) <= dist (p0, pM)) - p0 равно p2 </li>

В противном случае мы не можем определить, ближе ли минимум к p1 или к p2, поэтому мы будем использовать еще две точки для проверки: мы определим pL как среднюю точку между p1 и pMи pN как средняя точка между pM и p2.Теперь

  • if (dist (p0, pL) <= dist (p0, pM)) - p0 ближе к p1 </li>
  • if (dist (p0, pN) <=dist (p0, pM)) - p0 ближе к p2 </li>

В противном случае - p0 находится между pL и pN.

Таким образом, в каждой итерации мы делим вдвое длину дуги, в котороймы ищем решение.

Используя этот метод, мы можем получить точность в 1 см менее чем за 30 итераций.

4 голосов
/ 18 октября 2011

Я подробно остановлюсь на превосходном ответе Лиора Когана, используя геометрический (а не аналитический) подход.

Великий круг, содержащий "линию", лежит на плоскости, проходящей через центр сфероида.Эта плоскость ортогональна вектору, полученному как перекрестное произведение векторов, которые проходят через начало координат и, соответственно, p1 и p2.

Теперь мы ищем плоскость, ортогональную тому, который мы имеем, передаваядля р0.Это может быть легко вычислено, и пересечение этой плоскости со сфероидом должно ( ПРЕДУПРЕЖДЕНИЕ: я как бы тороплюсь, и я не уверен, что этот шаг математически обоснован ) будет большим кругом, ортогональным клиния".Пересечение дуг должно быть точкой, которую вы ищете, и может быть рассчитано как пересечение линии, общей для двух плоскостей (перекрестное произведение векторов, ортогональных каждой плоскости) и сфероида.

1 голос
/ 19 октября 2011

спасибо, что пытались научить меня, но я попросил простое прагматическое решение. Не математическая лекция:)

В любом случае, вот простой ответ:

Смотрите здесь: http://www.movable -type.co.uk / scripts / latlong.html

Рассчитать "Подшипник" (от начала линии до точки расстояния от каждого, который я хочу знать) + "Расстояние между точками".

Вот и все. мы сделали в несколько строк кода. нет итераций. без дополнительных библиотек. худой и средний

0 голосов
/ 07 июня 2016

Илья Голота ответ правильный, но, оказывается, он всегда возвращает действительно большое число, такое как «3.0355243098445522e12», даже для точек, которые находятся на расстоянии 2 метров от линии.Я сделал это для вычисления площади треугольника:

double d0 = computeDistanceBetween(p0, p1);
double d1 = computeDistanceBetween(p1, p2);
double d2 = computeDistanceBetween(p2, p0);

(по формуле Герона)

double area = Math.sqrt(halfP*(halfP-d0)*(halfP-d1)*(halfP-d2));

И затем вставьте здесь значение области

double distanceToLine = 2*area/computeDistanceBetween(line.startPoint, line.endPoint)

Это хорошо работает для меня и возвращает перпендикулярное расстояние от точки до линии в метрах.

0 голосов
/ 30 марта 2016

У вас есть линия, проходящая через точки земной поверхности A и B и точка C, от которой вы хотите вычислить расстояние.

Вы можете вычислить площадь треугольника ABC, разделив ее на расстояние между A и Bа затем умножить на 2.

function computeDistanceToLine(p, line) {
    var length = computeDistanceBetween(line.startPoint, line.endPoint);
    var triangleArea = computeTriangleArea(p, line.startPoint, line.endPoint);
    return 2 * triangleArea / length;
}

Алгоритм вычисления расстояния между двумя точками хорошо известен.Есть множество реализаций.Один из них (как отмечено в предыдущих ответах) можно найти там http://www.movable -type.co.uk / scripts / latlong.html

Для вычисления площади треугольника вы можете использовать некоторый алгоритмзависит от длины линии.Например

function computeTriangleArea(p0, p1, p2) {
    var r = 6378137;

    var d0 = computeDistanceBetween(p0, p1);
    var d1 = computeDistanceBetween(p1, p2);
    var d2 = computeDistanceBetween(p2, p0);

    var halfPerimeter = (d0 + d1 + d2) * 0.5;

    var t = Math.tan(halfPerimeter) *
        Math.tan((halfPerimeter - d0) * 0.5) *
        Math.tan((halfPerimeter - d1) * 0.5) *
        Math.tan((halfPerimeter - d2) * 0.5);

    return 4 * Math.atan(Math.sqrt(Math.abs(t))) * r * r;
}
0 голосов
/ 18 октября 2011

я раньше не работал с lon / lat, но .. я бы создал систему координат.центр земли, являющийся источником.преобразовать координаты lon / lat в систему координат

...