в моей программе на С++ в какой-то момент мне нужно рассчитать расстояние между двумя сферическими точками (заданными по азимуту и высоте) на сфере. Этот расчет нужно делать очень часто, но я не требую высокой точности (должно быть достаточно 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...
Есть ли смысл предварительно вычислять собственную таблицу поиска тригонометрических функций с пониженной точностью?
Если да, то как это должно выглядеть лучше всего (бинарный поиск или линейный, векторный или набор...)?