我正在制作一个函数,该函数使用它们的纬度/经度(以度而不是弧度为单位)和余弦球面定律来计算两点的距离。我遇到的问题是,由于函数中的舍入误差,acos()
当两点彼此非常接近时,我获得的结果远非良好。
#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;
}
输出是
arg=1.000000000000 acos(arg)=0.000000014901
dist=0.09496208
正如你所看到的,当它计算时acos()
它应该给出零,但它确实给出了一些误差,这些误差在乘以地球半径后会被极大地放大。当两点不相等但非常接近时也会发生这种情况。如果有任何用处,我关于纬度和经度的数据最多有 7 位小数。