Haversine 公式利用两点的纬度和经度,计算出球体表面两点间的最短距离。它在导航领域有着非常重要的作用。从三角函数的角度来看,haversine 可以表示为:
haversine(\theta)=sin^2\Big(\frac{\theta}{2}\Big)
我们通过以下公式计算中心角(即 d/r)的 haversine 值:
\largehaversine\Big(\frac{d}{r}\Big)=haversine(\Phi2-\Phi1)+ cos(\Phi1)cos(\Phi2)haversine(\lambda2-\lambda1)
其中,r 是地球半径(6371 公里),d 是两点之间的距离,\phi1 和 \phi2 是两点的纬度,\lambda1 和 \lambda2 则分别是两点的经度。
我们可以通过应用反 haversine 函数或使用反正弦函数来求解 d,公式如下:
d = r hav^{-1}(h) = 2r sin^{-1}(\sqrt{h})
或者
d = 2r sin^{-1}\bigg(\sqrt{sin^2\Big(\frac{\Phi2-\Phi1}{2}\Big)+cos(\Phi1)cos(\Phi2)sin^2\Big(\frac{\lambda2-\lambda1}{2}\Big)}\ \bigg)
以伦敦的大本钟(51.5007° N, 0.1246° W)和纽约的自由女神像(40.6892° N, 74.0445° W)为例,它们之间的距离为 5574.8 公里。请注意,这并不是完全精确的测量值,因为该公式假设地球是一个完美的球体,但实际上地球是一个扁球体。
下面是上述公式的具体实现代码:
C++
// C++ program for the haversine formula
// C++ program for the
// haversine formula
#include
#include
using namespace std;
static double haversine(double lat1, double lon1,
double lat2, double lon2)
{
// distance between latitudes
// and longitudes
double dLat = (lat2 - lat1) *
M_PI / 180.0;
double dLon = (lon2 - lon1) *
M_PI / 180.0;
// convert to radians
lat1 = (lat1) * M_PI / 180.0;
lat2 = (lat2) * M_PI / 180.0;
// apply formulae
double a = pow(sin(dLat / 2), 2) +
pow(sin(dLon / 2), 2) *
cos(lat1) * cos(lat2);
double rad = 6371;
double c = 2 * asin(sqrt(a));
return rad * c;
}
// Driver code
int main()
{
double lat1 = 51.5007;
double lon1 = 0.1246;
double lat2 = 40.6892;
double lon2 = 74.0445;
cout << haversine(lat1, lon1,
lat2, lon2) << " K.M.";
return 0;
}
// This code is contributed
// by Mahadev.
Java
// Java program for the haversine formula
public class Haversine {
static double haversine(double lat1, double lon1,
double lat2, double lon2)
{
// distance between latitudes and longitudes
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
// convert to radians
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
// apply formulae
double a = Math.pow(Math.sin(dLat / 2), 2) +
Math.pow(Math.sin(dLon / 2), 2) *
Math.cos(lat1) *
Math.cos(lat2);
double rad = 6371;
double c = 2 * Math.asin(Math.sqrt(a));
return rad * c;
}
// Driver Code
public static void main(String[] args)
{
double lat1 = 51.5007;
double lon1 = 0.1246;
double lat2 = 40.6892;
double lon2 = 74.0445;
System.out.println(haversine(lat1, lon1, lat2, lon2) + " K.M.");
}
}
Python 3
# Python 3 program for the
# haversine formula
import math
# Python 3 program for the
# haversine formula
def haversine(lat1, lon1, lat2, lon2):
# distance between latitudes
# and longitudes
dLat = (lat2 - lat1) * math.pi / 180.0
dLon = (lon2 - lon1) * math.pi / 180.0
# convert to radians
lat1 = (lat1) * math.pi / 180.0
lat2 = (lat2) * math.pi / 180.0
# apply formulae
a = (pow(math.sin(dLat / 2), 2) +
pow(math.sin(dLon / 2), 2) *
math.cos(lat1) * math.cos(lat2));
rad = 6371
c = 2 * math.asin(math.sqrt(a))
return rad * c
# Driver code
if __name__ == "__main__":
lat1 = 51.5007
lon1 = 0.1246
lat2 = 40.6892
lon2 = 74.0445
print(haversine(lat1, lon1,lat2, lon2), "K.M.")
# This code is contributed
# by ChitraNayal
C#
// C# program for the haversine formula
using System;
class GFG
{
static double haversine(double lat1, double lon1,
double lat2, double lon2)
{
// distance between latitudes and longitudes
double dLat = (Math.PI / 180) * (lat2 - lat1);
double dLon = (Math.PI / 180) * (lon2 - lon1);
// convert to radians
lat1 = (Math.PI / 180) * (lat1);
lat2 = (Math.PI / 180) * (lat2);
// apply formulae
double a = Math.Pow(Math.Sin(dLat / 2), 2) +
Math.Pow(Math.Sin(dLon / 2), 2) *