LeoVannini
LeoVannini

Reputation: 95

great circle distance c++

I've included code (now) for the great circle distance formula. Code works until one of the lats/longs has S/E attached as their respective directions ( I attempted to use S/E as "negative directions"). Any help is extremely appreciated!

#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;

 }

Input: 23.4356/S 46.4731/W

Distance Output: 4335.48

Upvotes: 0

Views: 2742

Answers (2)

Bathsheba
Bathsheba

Reputation: 234705

Aside from the programming errors (see @David Schwartz), your approach is deficient in that you will lose too much precision; especially when the end points are proximate. (Very simply, mixing pow with trigonometric functions is a recipe for excessive precision loss in floating point).

You ought to use Vincenty instead. See http://en.wikipedia.org/wiki/Vincenty%27s_formulae.

And use M_PI if your compiler supports it, or define PI to the limit of double precision.

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182761

You don't use the return values of the various direction check functions or the positivify function and they take their parameters by value. So they have no effect. You either need to pass them parameters by reference or use their return values. Otherwise, they compute a value and return it to code that ignores it.

Upvotes: 1

Related Questions