使用勾股定理计算两点之间的距离

7
我希望创建一个函数,使用勾股定理而不是haversine大圆公式来计算两个经纬度对之间的距离。由于此函数将用于相对较短的距离(3公里),因此我认为这个假设地球是平的版本应该没有问题。我该如何做?我在互联网上查找并没有发现任何有用的信息。:)
谢谢。
编辑:
这是我想到的代码(似乎可行):
def get_dist(lat0, lng0, lat1, lng1)
  begin
    d_ew = (lng1.to_f - lng0.to_f) * Math.cos(lat0.to_f)
    d_ns = (lat1.to_f - lat0.to_f)
    d_lu = Math.sqrt(d_ew.to_f * d_ew.to_f + d_ns.to_f * d_ns.to_f)
    d_mi = ((2*Math::PI*3961.3)/360)*d_lu
    return d_mi
  rescue Exception => ex
    logger.debug "[get_dist] An exception occurred: #{ex.message}"
    return -1
  end
end

15
有史以来最好的格言:“我向互联网提问,但没有得到任何有用的答案。” - Michael Haren
肯定会在我的网站上使用它来生成报价。 - user
我建议你尽力而为,我们从那里开始(发布你目前为止的内容!) - Michael Haren
确实是一句很棒的话。我找到了一个链接,其中包含所有各种方程式Calculate distance - uadrive
3个回答

17

如果你预计所涉及的距离与地球的大小相比较小,可以使用简单的勾股定理三角形。

假设你在点 (lat0, long0),想知道到点 (lat1, long1) 的距离,以"纬度单位"计算。

水平(东西向)距离大致上是

d_ew = (long1 - long0) * cos(lat0)

这个值乘以cos(lat0),以考虑在高纬度时经线越来越接近的情况。

垂直(NS)距离更容易计算。

d_ns = (lat1 - lat0)

所以这两点之间的距离是

d = sqrt(d_ew * d_ew + d_ns * d_ns)
你可以优化这个方法以实现更精确的任务,但是这应该足够用于比较距离。
事实上,对于比较距离而言,比较d的平方就足够了,这意味着你可以省略sqrt操作。

++1 - 你的比我的简单,所以我删掉了我的。 - James Black
出于好奇,如果我得到了水平距离,有没有办法将其转换为公里或英里? - cakeforcerberus
cakeforcerberus,你是一个严格的任务大师。这并不是那么简单的原因有几个。其中之一是地球不是一个球体。你可以通过假装它是一个球体来得到一个粗略的估计。然后你可以计算出“纬度单位”是相应于一度纬度的距离。这是2 * pi * R / 360.0,其中R是地球的半径。要比这更好的估计,模型很快就会变得复杂。 - Ewan Todd
该死的扁球体!:D 你能为我拼出来吗?如果我假设一个完美的球体,并且有一个距离为0.0023纬度单位,我可以通过什么方式得到英里数? - cakeforcerberus
5
好的。让我们在谷歌中尝试这个:2 * pi * 3959 / 360 看起来是69.0975851英里。保留尽可能多的有效数字直到最后一步。您不会在其他任何地方找到"纬度单位"这个术语,我是自己编的。因此,如果您的纬度和经度是以度为单位的,则将上面的d乘以此数以近似英里为单位的距离。0.0023 * 69.0975851英里=0.158924445英里。将其舍入到与0.0023相同的精度,并且是0.16英里。如果与您预期的有所不同,请勿起诉我。 - Ewan Todd
2
小调整:将 * cos(lat0) 替换为 * cos(average(lat0, lat1))。这样可以更好地近似距离。 - ToolmakerSteve

4

由于您的点彼此接近,因此球体表面几乎是平的,因此只需在三维空间中找到每个点的坐标(x,y,z)即可。请找出每个点的坐标。

x = r*sin(lat)*cos(long)
y = r*sin(lat)*sin(long)
z = r*cos(lat)

其中r是球体的半径,具体取决于如何定义经纬度。一旦获得了两个xyz坐标,只需使用sqrt((x1-x2)^2+(y1-y2)^2+(z1-z2)^2)即可。你真的不能仅仅使用二维勾股定理,因为你需要获得合理的二维坐标,这很困难。


将这种方法的结果与我的2D勾股定理和cos(lat)进行比较肯定是值得的。你可能会得到更可接受的结果。 - Ewan Todd
@EwanTodd - 对于一个球体,我相信您的方法(沿着表面的两个距离,被视为直角三角形)会导致正确答案的上限(如果在纬度和经度中都有显著移动,则估计距离过大),而直接进行3D计算,即在球体内部的一条直线,会得出下限。不明显哪种更接近,或在什么情况下。 - ToolmakerSteve

1
通常你会看到这种表示法 'dy, dx',它代表着 y 的差异和 x 的差异。你只需要计算出两个轴上的差异,然后按照定理求出两个差异的平方和的平方根。(即勾股定理:直角三角形斜边的平方等于另外两条边的平方和)
var dx:Number = x1-x2;
var dy:Number = y1-y2;
var distance:Number = Math.sqrt(dx*dx + dy*dy);

希望这足够清晰明了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接