3

获取地球两点的距离

最近在做小程序的时候遇到要计算两点之间的距离,但小程序没有相关的方法,只好自己来了.

背景知识

地球的半径

地球虽然是个椭圆,但也极像个正圆(相差大概20公里),所以就按正圆来算了,半径是6371.393公里.

弧长公式

L = 弧度 * R = 圆心角度数 × π × R / 180

余弦定律

2abcosC=a^2+b^2-c^2
c^2 = a^2+b^2-2abcosC

模型

图片描述

思路

  1. 假设求A,B两点的距离,半径已经知道了,
  2. 现在只需求∠AOB弧度.
  3. 但∠AOB弧度可以通过AB的长度获得

运算过程

根据上面的图算

假设A坐标(JA,WA),B坐标(JB,WB).
即∠AOC = WA, ∠BOD = WB.

根据三角形函数

AC = sin(WA) R, BD = sin(WB) R
所以 BE = BD - AC

因为∠COD = (JB - JA), 根据余弦定律
CO = cos(WA) R, DO = cos(WB) R
所以 AE = CD = 根号[CO^2 + DO^2 - 2 CO DO * cos(∠COD)]

根据勾股定律
AB^2 = AE^2 + BE^2

因为∆AOB是等腰三角形,三线合一,GO为垂直平分线
AB^2 = 2R^2 - 2R^2 * cosC;
cosC = [2R^2 - AB^2] / 2R^2;
简化的
∠AOB弧度 = acos[sin(WA)sin(WB) + cos(WA)cos(WB)cos(JB-JA)]

L = ∠AOB弧度 * R

代码

function _Radian(num) {
    return num * Math.PI / 180;
}

function CalculateDistance(lata, lnga, latb, lngb) {
    var earthR = 6371.393;
    var WA, WB;
    WA         = _Radian(lata);
    WB         = _Radian(latb);

    var lngMinus  = Math.abs(lngb - lnga) > 180? 360 - Math.abs(lngb - lnga): Math.abs(lngb - lnga);
    var lngRadian = _Radian(lngMinus);
    var ANGLE     = Math.sin(WA) * Math.sin(WB) + Math.cos(WA) * Math.cos(WB) * Math.cos(lngRadian);
    var L         = Math.acos(ANGLE) * earthR;
    return L;
}

用_Radian发角度转化为弧度.
因为取两点的最小值,所以但经度之间差大于180时,再用360 - 经度差,取最小经度差.


lea_
253 声望19 粉丝

在有限时间,做最好自己.


« 上一篇
https那些事
下一篇 »
webpack的优化