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