расстояние по большому кругу С++

Я включил код (сейчас) для формулы расстояния по большому кругу. Код работает до тех пор, пока к одному из широчайших/длинных направлений не будет присоединено S/E в качестве соответствующих направлений (я пытался использовать S/E как «отрицательные направления»). Любая помощь очень ценится!

#include <iostream>
#include <math.h>
#include "lat.hpp"
#include <string>

#define PI 3.14159265


double greatCircleDistance(double lat1, double long1, char latDir1 ,
                            char longDir1, double lat2, double long2,
                            char latDir2, char longDir2)
  {
  double dLat;
  double dLong;

   latDirectionCheck(latDir1, lat1);
   latDirectionCheck(latDir2, lat2);
   longDirectionCheck(longDir1, long1);
   longDirectionCheck(longDir2, long2);

   dLat = (lat1 - lat2) ;
   dLong = (long1 - long2);

   positivify(dLat);
   positivify(dLong);
   positivify(lat1);
   positivify(lat2);

    //convert all numbers to Rad
    dLat = convertRadians(dLat);
    dLong = convertRadians(dLong);
    lat1 = convertRadians(lat1);
    lat2 = convertRadians(lat2);

    double R = 3959.9;
    double num1 = sin(dLat/2);
    double num2 = sin(dLong/2);



    double a = pow(num1,2) + cos(lat1) * cos(lat2) *
               pow(num2,2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = R * c;
    return d;
   }

 double latDirectionCheck(char check, double convert) {
     if(check == 'S') 
      convert = -convert;
      return convert;
 }

 double longDirectionCheck(char check, double convert) {
    if(check == 'E')
       convert = -convert;
       return convert;
    }

 double positivify(double num) {
    if (num < 0) 
    num = num*(-1);
    return num;
 }

 bool compareFarDistance(double num1, double num2) {
    bool statement = false;
    if(num1 > num2)
        statement = true;
        return statement; 
 }

 bool compareCloseDistance(double num1, double num2) {
    bool statement = false;
    if(num1 < num2)
        statement = true;
        return statement;
 }
 double convertRadians(double num) {
   num = PI*(num/180);
   return num;
 }

 double convertDegrees(double num) {
    num = 180 * (num/PI);
    return num;

 }

Ввод: 23.4356/S 46.4731/W

Выход расстояния: 4335.48


person LeoVannini    schedule 16.10.2013    source источник
comment
Пожалуйста, опубликуйте минимальный пример   -  person Vittorio Romeo    schedule 17.10.2013
comment
Можете ли вы описать более пример ввода/вывода, который не работает? например, откуда вы знаете, что это не работает?   -  person pippin1289    schedule 17.10.2013
comment
positivify делает в основном то же самое, что fabs или абсолютное значение с плавающей запятой. Убедитесь, что вы используете стандартные библиотечные функции, когда это возможно.   -  person pippin1289    schedule 17.10.2013


Ответы (2)


Вы не используете возвращаемые значения различных функций проверки направления или функции positivify, и они принимают свои параметры по значению. Поэтому они не имеют никакого эффекта. Вам нужно либо передать им параметры по ссылке, либо использовать их возвращаемые значения. В противном случае они вычисляют значение и возвращают его коду, который его игнорирует.

person David Schwartz    schedule 16.10.2013
comment
После ссылки на возвращаемые значения в коде (dLat = latDirectionCheck(latDir1, lat1) , я все еще получаю тот же ответ? Я пропустил больше? - person LeoVannini; 17.10.2013
comment
@DavidSchwartz У меня все работает! Большое спасибо. Я не могу поверить, что пересмотрел связь обновленного dLat с возвращаемым значением. Что касается pow-функции с тригонометрическими функциями, я сделал этот ленточный ход только потому, что это относительно моя первая крупная программа на C++, и я не знал, как использовать экспоненты. Ответ ниже, связанный с Винсенти, не имеет смысла, и я бы предпочел не реализовывать формулы, в которых я мало что понимаю. Но еще раз, спасибо, что указали на мой ответ! Ты спасатель жизни Дэвид! - person LeoVannini; 17.10.2013

Помимо ошибок программирования (см. @David Schwartz), ваш подход несовершенен, поскольку вы потеряете слишком много точности; особенно когда конечные точки близки. (Проще говоря, смешивание pow с тригонометрическими функциями - это рецепт чрезмерной потери точности в вычислениях с плавающей запятой).

Вместо этого вы должны использовать Винсенти. См. http://en.wikipedia.org/wiki/Vincenty%27s_formulae.

И используйте M_PI, если ваш компилятор поддерживает это, или определите PI до предела двойной точности.

person Bathsheba    schedule 16.10.2013