为什么 Lua lat/long 的 Haversine 代码不起作用?

How come this Lua Haversine code for lat/long won't work?

我正在尝试创建一个半轴“距离计算器”,我可以在其中输入两个 lat/long 坐标,它会通过使用半轴公式给出它们之间的距离。它在 Lua 中,代码如下:

local R = 6371000 -- metres
local lat1 =  la1 * math.pi/180
local lat2 = la2 * math.pi/180
local dlat = (lat2 - lat1) * math.pi/180
local dlong = (long2 - long1) * math.pi/180

local a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(lat1) * math.cos(lat2) * math.sin(dlong/2) * math.sin(dlong/2)
local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))

local d = R * c -- in metres
d = d / 1000 -- in kilometers

print(d)

我已经针对使用此公式的多个在线距离检查器对其进行了测试,并且总是有很大差距。而且,我从这里获取了代码,然后将其更改为 Lua:https://www.movable-type.co.uk/scripts/latlong.html

知道为什么这不起作用吗?谢谢。

假设您只是省略了设置坐标的行,您的问题是您将 dlat 乘以 math.pi/180,尽管 lat1lat2已经是弧度,而不是度数。 local dlat 应该是 lat2 - lat1.

下面是代码的改进变体:

local function haversine (lat1, lat2, long1, long2) -- in radians.
    local cos, sin = math.cos, math.sin
    local dlat, dlong = lat2 - lat1, long2 - long1
    return sin (dlat / 2) ^ 2 + cos (lat1) * cos (lat2) * sin (dlong / 2) ^ 2
end

local function distance (p1, p2) -- in degrees.
    local pi, arcsin, sqrt = math.pi, math.asin, math.sqrt
    local d2r = pi / 180

    local R = 6371000 -- in metres

    local lat1, lat2 =  p1[1] * d2r, p2[1] * d2r
    local long1, long2 = p1[2] * d2r, p2[2] * d2r
    
    local a = haversine (lat1, lat2, long1, long2)

    return 2 * R * arcsin (sqrt (a)) / 1000 -- in km
end


local Moscow, Novokuznetsk = {55.7558, 37.6173}, {53.7596, 87.1216}
print (distance (Moscow, Novokuznetsk)) -- 3126 km as reported by https://www.distancefromto.net/distance-from-moscow-to-novokuznetsk-ru.
  • distancehaversine 被移动到函数,
  • 来自 math 的功能已本地化,以获得更整洁的外观和性能,
  • 度数到弧度的转换率是为提高性能而预先计算的,
  • ^用于电源,
  • 反正切替换为反正弦,以简化公式。