Если вы не возражаете, игнорируя небольшое сжатие Земли (и ваш опубликованный код Хаверсайна так или иначе делает именно это), рассмотрите возможность предварительного преобразования всех ваших сферических (широтных / длинных) координат в 3D единицу длины * Сначала 1002 * декартовых координат, по:
http://en.wikipedia.org/wiki/Spherical_coordinate_system
Тогда ваше сферическое расстояние между декартовыми координатами p1
и p2
просто:
r * acos(p1 . p2)
Поскольку p1
и p2
будут иметь длину блока, это сокращает до четырех умножений, двух сложений и одной операции обратного триггера на пару.
Также обратите внимание, что расчет точечных произведений является идеальным кандидатом для оптимизации, например, через GPU, MMX-расширения, векторные библиотеки и т. д.
Кроме того, если вы хотите упорядочить пары по расстоянию, потенциально игнорируя более удаленные пары, вы можете отложить дорогую r*acos()
часть уравнения, отсортировав список только по значению точечного произведения. поскольку для всех допустимых входных данных (т. е. диапазона [-1, 1]
) гарантируется, что:
acos(x) < acos(y) if x > y
Затем вы просто берете acos()
значений, которые вам действительно интересны.
Re: потенциальные неточности при использовании acos()
, они действительно существенны, только если вы используете переменные float
с одинарной точностью. Использование double
с 16 значащими цифрами должно дать вам точное расстояние с точностью до одного метра или менее.