智游城

标题: 计算地球上两点间距离 [打印本页]

作者: 老陈    时间: 2014-7-27 03:30
标题: 计算地球上两点间距离
本帖最后由 老陈 于 2014-7-26 13:32 编辑

已知地球上两点的经纬度,求两点间最短距离。

网上有公式,没有详细的推导过程。求:公式推导的详细过程。
作者: 老陈    时间: 2014-7-29 07:42
本帖最后由 老陈 于 2014-7-28 17:44 编辑

+(double)calculateDistanceFromLatitude (double)fromLatitude     //纬度  北纬为正,南纬为负
                      andFromLongitude (double)fromLongitude    //经度  东经为正,西经为负
                       andFromAltitude (double)fromAltitude     //海拔高度 单位:米
                            toLatitude (double)toLatitude
                        andToLongitude (double)toLongitude
                         andToAltitude (double)toAltitude
{

    double tDDegreeToRadian=asin(0.5)/30.0;
    double tDradianLong            = 6378.140;     // 赤道半径
    double tDradianShort           = 6356.755;     // 两极半径

    double tDFromLatitude  = fromLatitude   * tDDegreeToRadian;
    double tDToLatitude    = toLatitude     * tDDegreeToRadian;
    double tDFromLongitude = fromLongitude  * tDDegreeToRadian;
    double tDToLongitude   = toLongitude    * tDDegreeToRadian;
    //  角度转换成弧度
    double tDFromAltitude  = fromAltitude   / 1000.0;
    double tDToAltitude    = toAltitude     / 1000.0;
    //  米转换成公里
    double radian= sin(tDFromLatitude)*sin(tDToLatitude) + cos(tDFromLongitude-tDToLongitude) * cos(tDFromLatitude)*cos(tDToLatitude);
    double tDistance = 6371.004*acos(radian);
    //  用网上公式估算距离
    NSInteger tIStep=tDistance*100;
    // 按约10米为步长计算
    tDistance=0.0;
    double Latitude0=(tDToLatitude-tDFromLatitude)/tIStep;
    double Latitude1=tDFromLatitude;
    double Latitude2=0;
    double Longitude0=(tDToLongitude-tDFromLongitude)/tIStep;
    double Longitude1=tDFromLongitude;
    double Longitude2=0;
    double Altitude0=(tDToAltitude-tDFromAltitude)/tIStep;
    double Altitude1=tDFromAltitude;
    double Altitude2=0.0;
    double mDistance=0.0;

    NSInteger i;
    for(i=0;i<tIStep;i++)
    {
        Latitude2  = Latitude1  + Latitude0;
        Longitude2 = Longitude1 + Longitude0;
        Altitude2  = Altitude1  + Altitude0;

        double z1=sin(Latitude1)*(tDradianShort+Altitude1);
        double x1=cos(Latitude1)*cos(Longitude1)*(tDradianLong+Altitude1);
        double y1=cos(Latitude1)*sin(Longitude1)*(tDradianLong+Altitude1);
        double z2=sin(Latitude2)*(tDradianShort+Altitude1);
        double x2=cos(Latitude2)*cos(Longitude2)*(tDradianLong+Altitude2);
        double y2=cos(Latitude2)*sin(Longitude2)*(tDradianLong+Altitude2);
        //  球面坐标转换成笛卡尔坐标
        double xd=x2-x1;
        double yd=y2-y1;
        double zd=z2-z1;
        double tDLineDistance=sqrt(xd*xd+yd*yd+zd*zd);
        // 两点间直线距离
        double tDRadiusFrom=sqrt(x1*x1+y1*y1+z1*z1);
        double tDRadiusTo=sqrt(x2*x2+y2*y2+z2*z2);
        // 两点到地心距离
        double tDAngle=acos((tDRadiusFrom*tDRadiusFrom+tDRadiusTo*tDRadiusTo-tDLineDistance*tDLineDistance)/(2.0*tDRadiusFrom*tDRadiusTo));
        // 用余玄定理计算角度

        mDistance+=tDAngle*(tDRadiusFrom+tDRadiusTo)/2.0;
        // 计算距离并累加

        Latitude1+=Latitude0;
        Longitude1+=Longitude0;
        Altitude1+=Altitude0;
    }
    return mDistance;
}



作者: leisong    时间: 2014-7-29 10:00
这...
作者: fastfast    时间: 2014-7-29 17:39
提示: 作者被禁止或删除 内容自动屏蔽
作者: 老陈    时间: 2014-7-29 19:51
本帖最后由 老陈 于 2014-7-29 12:21 编辑
fastfast 发表于 2014-7-29 03:39
搞出更简单的方法才NB


网上这个简单,公式如下:
   double radian= sin(tDFromLatitude)*sin(tDToLatitude) + cos(tDFromLongitude-tDToLongitude) * cos(tDFromLatitude)*cos(tDToLatitude);
    double tDistance = 6371.004*acos(radian);

这个公式在计算纬度在30-60之间时误差较小,其它地方误差较大,最大误差可达0.3%。
因为这个公式做了个假设:就是地球时标准球体,即各个地方半径都一样。但事实不是这样。
再有这个公式忽略了高度,一个很陡的山顶和山脚的距离,用这个公式会算出可笑的结果。

目前我还没找到即准确又简单的方法。




作者: luckypanda    时间: 2014-7-30 10:49
你们好无聊。
作者: 老陈    时间: 2014-7-30 11:52
luckypanda 发表于 2014-7-29 20:49
你们好无聊。

探讨科学,无止境啊!
作者: luckypanda    时间: 2014-7-30 12:22
老陈 发表于 2014-7-29 22:52
探讨科学,无止境啊!

科学对我来说太枯燥了。
作者: 老陈    时间: 2014-7-30 12:35
luckypanda 发表于 2014-7-29 22:22
科学对我来说太枯燥了。

人类社会的进步,就是因为有很多人探讨科学。
作者: fastfast    时间: 2014-7-30 19:21
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 智游城 (http://zhiyoucheng.co/) Powered by Discuz! X3.2