отличная производительность на дистанции круга

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

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

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

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

или же

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

или же

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 …

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

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

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …