如果您不介意忽略地球的微小扁圆度(无论如何,您发布的Haversine代码也可以做到这一点),请考虑将每个球形(纬度/经度)坐标首先预先转换为3D
单位长度的 笛卡尔坐标,具体如下:
http://en.wikipedia.org/wiki/Spherical_coordinate_system
然后直角坐标系之间的球面距离
p1,并
p2很简单:
r * acos(p1 . p2)
由于
p1并且
p2将具有单位长度,因此每对减少为四个乘法,两个加法和一个反向触发操作。
还要注意,点积的计算是优化的理想选择,例如通过GPU,MMX扩展,向量库等。
此外,如果您打算按距离对对 排序
,可能会忽略更远的对,则可以
r*acos()通过仅对点乘积值进行排序来推迟等式的昂贵部分,因为对于所有有效输入(即范围
[-1,1]),都可以保证那:
acos(x) < acos(y) if x > y
然后,您只需选择
acos()您真正感兴趣的值即可。
关于:使用的潜在错误,
acos()仅在使用单精度
float变量时,这些错误才真正重要。使用
double包含16个有效数字的数字,您可以将距离准确地控制在1米以内。



