Начнем с некоторых предположений:
Итак, перефразируя ваш вопрос:
Учитывая три точки земной поверхности - 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 итераций.