You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何基于笛卡尔坐标与经纬度计算的两点距离结果存在差异?

经纬度转笛卡尔坐标后距离计算不一致的原因

我有一组经纬度点,先用以下distance函数计算两点间距离,再通过X_Y_Z函数将经纬度转换为笛卡尔坐标,随后用公式$(x2+y2+z2){0.5}$计算距离,结果和第一种方法不同,请问原因是什么?

代码实现

import math

def distance(lat2, lat1, lon2, lon1):
    distance = []
    speed = []
    accelerate = []

    radius = 6371  # km
    dlat = math.radians(lat2 - lat1)
    dlon = math.radians(lon2 - lon1)
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
        * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    d = radius * c
    distance.append(d)
    
    for i in range(len(distance)-1):
        speed.append((distance[i])/0.25)
    for i in range(len(speed)-1):
        accelerate.append((speed[i+1]-speed[i])/0.25)
    return distance, speed, accelerate


def X_Y_Z(latitude, longitude):
    R = 6371
    X = []
    Y = []
    Z = []

    for lat, lon in zip(latitude, longitude):
        x = R * math.cos(lat) * math.cos(lon)
        y = R * math.cos(lat) * math.sin(lon)
        z = R * math.sin(lat)
        X.append(x)
        Y.append(y)
        Z.append(z)
    return X, Y, Z

示例问题

例如,点(40.714531,-73.725607)与(40.714527,-73.725591)用经纬度计算的距离为0.001377km,但对应的笛卡尔坐标(642.430295,-6287.620268,801.720448)与(642.527042,-6287.607109,801.746119)计算出的距离却不同。


问题原因分析

  • 笛卡尔坐标转换未做弧度转换:
    X_Y_Z函数直接使用原始的经纬度(单位是度)调用math.cos和math.sin,但Python的三角函数默认接收弧度值。而distance函数里已经正确将经纬度转为弧度计算,这导致笛卡尔坐标的计算结果完全错误,自然两点间距离和Haversine公式结果不一致。

  • 两点间距离计算逻辑错误:
    你使用的$(x2+y2+z2){0.5}$是单个笛卡尔坐标点到原点的距离(理论上等于地球半径6371km),不是两点之间的欧氏距离。正确的两点笛卡尔距离应该计算坐标差的模:$\sqrt{(x_2-x_1)^2 + (y_2-y_1)^2 + (z_2-z_1)^2}$。不过即使修正这个逻辑,因为第一个问题的存在,结果还是会和Haversine公式不符。


修正后的代码

只需在X_Y_Z函数中添加弧度转换:

import math

def X_Y_Z(latitude, longitude):
    R = 6371
    X = []
    Y = []
    Z = []

    for lat, lon in zip(latitude, longitude):
        # 将经纬度从度转为弧度
        lat_rad = math.radians(lat)
        lon_rad = math.radians(lon)
        x = R * math.cos(lat_rad) * math.cos(lon_rad)
        y = R * math.cos(lat_rad) * math.sin(lon_rad)
        z = R * math.sin(lat_rad)
        X.append(x)
        Y.append(y)
        Z.append(z)
    return X, Y, Z

修正后,用正确的欧氏距离公式计算两点笛卡尔坐标的距离,结果会和distance函数的Haversine公式结果基本一致(误差仅来自浮点运算精度)。


内容的提问来源于stack exchange,提问作者user15649753

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 03:35:27