I am making a function that calculates the distance of two points using their latitude/longitude (in degrees not radians) and the spherical law of cosines. The problem I have is that due to rounding errors in the function acos()
the results I am obtaining are far from good when the two points are very close to each other.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct{
double lat;
double lon;
} point;
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define EARTH_RADIUS_IN_METERS 6372797.560856
double distance(point a, point b) {
double arg=sin(a.lat * DEG_TO_RAD) * sin(b.lat * DEG_TO_RAD) + cos(a.lat * DEG_TO_RAD) * cos(b.lat * DEG_TO_RAD) * cos((a.lon-b.lon) * DEG_TO_RAD);
if(arg>1) arg=1;
else if (arg<-1) arg=-1;
printf("arg=%.12f acos(arg)=%.12f\n",arg, acos(arg)); //to see the problem
return acos(arg) * EARTH_RADIUS_IN_METERS;
}
int main(){
point p1,p2;
p1.lat=63.0;
p1.lon=27.0;
p2.lat=p1.lat;
p2.lon=p1.lon;
printf("dist=%.8f\n",distance(p1,p2));
return 0;
}
The output is
arg=1.000000000000 acos(arg)=0.000000014901
dist=0.09496208
as you can see, when it computes the acos()
it should give zero but it does give some errors that get enormously magnified after multiplying by the earth radius. It also happens when the two points are not equal but very close. If it is of any use my data about latitude and longitude has up to 7 decimal digits.