дальность большого круга

в моей программе на С++ в какой-то момент мне нужно рассчитать расстояние между двумя сферическими точками (заданными по азимуту и ​​высоте) на сфере. Этот расчет нужно делать очень часто, но я не требую высокой точности (должно быть достаточно 1 градуса). (Расстояния указаны во всех диапазонах [0-180])

Я использовал профайлер (valgrind) для поиска узких мест. Выяснилось, что 70% времени выполнения я трачу на расчет расстояния по большому кругу. В этой функции 60% моего времени уходит на вычисление синуса или косинуса или других тригонометрических функций...

Я пробовал разные подходы: (все используют пространство имен std;)

double tmp = sin(el1) * sin(el2) + cos(el1) * cos(el2) * cos(az1-az2);
double distance = acos(tmp);

or

typedef boost::geometry::model::point<double, 2, boost::geometry::cs::spherical_equatorial<boost::geometry::radian> > spherical_point;
spherical_point p1(az2,el2);
spherical_point p2(az1,el2);
double distance = hv.apply(p1,p2); % here hv is a haversine<double> object

or

double daz_half = (az2 - az1)/2;
double del_half = (el2 - el1)/2;
double tel = sin(del_half);
double taz = sin(daz_half);
double a = tel*tel + cos(el2) * cos(el1) * taz * taz ;
double distance = 2*atan2(sqrt(a),sqrt(1-a));

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

Кто-нибудь знает хорошее приближение для формулы расстояния по большому кругу с пониженной точностью?

Или кто-нибудь знает, как ускорить вычисление sin cos acos atan2...

Есть ли смысл предварительно вычислять собственную таблицу поиска тригонометрических функций с пониженной точностью?

Если да, то как это должно выглядеть лучше всего (бинарный поиск или линейный, векторный или набор...)?


person user7431005    schedule 02.08.2017    source источник
comment
Во встроенных системах мы обычно используем таблицы поиска для триггерных функций - я бы попробовал.   -  person systemcpro    schedule 02.08.2017
comment
Здесь был аналогичный вопрос вопросы/650797/   -  person AdityaG    schedule 02.08.2017
comment
Каковы ваши данные точки? Если вы не создаете много точек на месте и для каждой точки рассчитано несколько расстояний, вы можете предварительно вычислить синусы и косинусы для азимута и высоты каждой точки.   -  person M Oehm    schedule 02.08.2017
comment
И, возможно, вы могли бы сэкономить некоторые вычисления, если бы вы разработали алгоритм для расчета расстояния по большому кругу, чтобы ему не приходилось так часто вызывать функцию расстояния. Это зависит, конечно, от того, чего вы хотите достичь.   -  person M Oehm    schedule 02.08.2017
comment
Спасибо за вашу помощь... Я создал собственную справочную таблицу, которая уже стала большим улучшением.   -  person user7431005    schedule 02.08.2017
comment
к сожалению, моя точка каждый раз выглядит немного по-разному, поэтому я не могу ее предварительно вычислить. Я немного поиграю с таблицами поиска. Прямо сейчас я создал собственный поиск классов со статической неупорядоченной картой.   -  person user7431005    schedule 02.08.2017
comment
Возьмите первые два члена расширения ряда en.wikipedia.org/wiki/Taylor_series#Trigonometric_functions   -  person stark    schedule 02.08.2017
comment
@user7431005: user7431005: Вы должны быть в состоянии добиться большего успеха, чем карта, генерируя равномерно распределенные выборки и ища значение (или два для интерполяции) с индексом массива из масштабирования ввода.   -  person Davis Herring    schedule 26.04.2019