计算两个经纬度之间的距离

    /// <summary>
    /// 获取两个经纬度之间的距离
    /// </summary>
    /// <param name="LonA">经度A</param>
    /// <param name="LatA">纬度A</param>
    /// <param name="LonB">经度B</param>
    /// <param name="LatB">经度B</param>
    /// <returns>距离(千米)</returns>
    public static double getDistance(double LonA, double LatA, double LonB, double LatB)
    {
        // 东西经,南北纬处理,只在国内可以不处理(假设都是北半球,南半球只有澳洲具有应用意义)
        double MLonA = LonA;
        double MLatA = LatA;
        double MLonB = LonB;
        double MLatB = LatB;
        // 地球半径(千米)
        double R = 6371.004;
        double C = Math.Sin(rad(LatA)) * Math.Sin(rad(LatB)) + Math.Cos(rad(LatA)) * Math.Cos(rad(LatB)) * Math.Cos(rad(MLonA - MLonB));
        return (R * Math.Acos(C));
    }

    private static double rad(double d)
    {
        return d * Math.PI / 180.0;
    }


 

<think>嗯,用户想用STM32计算两个经纬度距离,用的是Haversine公式。首先我得确认Haversine公式的具体内容,对吧?记得这个公式是用来计算球面上两点间的大圆距离的,适用于经纬度坐标。那公式应该是这样的:a = sin²(Δφ/2) + cosφ1 * cosφ2 * sin²(Δλ/2),然后c = 2 * atan2(√a, √(1−a)),最后距离d = R * c。其中φ是纬度,λ是经度,R是地球半径,大概是6371公里。 接下来要考虑的是如何在STM32上实现这个公式。STM32是微控制器,资源有限,可能需要用C语言编写代码,并且要注意浮点运的处理。用户可能需要将经纬度从度数转换为弧度,因为三角函数通常使用弧度。转换公式是弧度 = 度数 * π / 180。这里需要注意π的值,可以用3.14159265358979323846这样的近似值。 然后要考虑代码的结构。首先定义一个函数,输入四个浮点数参数:lat1、lon1、lat2、lon2,返回距离。在函数内部,先将角度转换为弧度,然后计算纬度和经度的差值Δlat和Δlon。接着应用Haversine公式的各个步骤,计算a和c,最后得到距离。需要注意的是,三角函数如sin、cos,以及平方根和反正切函数的使用,STM32的数学库是否支持这些函数,可能需要包含math.h头文件,并链接数学库,比如在编译时加上-lm。 还有,用户可能需要考虑浮点运的精度问题。STM32有的型号有硬件FPU,有的没有,如果使用没有FPU的型号,浮点运可能会比较慢,但Haversine公式的计算量不太大,应该还是可以处理的。另外,地球半径R的选择,如果用户需要更高的精度,可能需要用更精确的R值,比如6378.137公里,或者根据应用场景调整。 另外,测试代码是否正确也是重要的。比如,可以测试两个相同的点,距离应该为0。或者已知的两个坐标点,比如北京和上海的经纬度,看看计算结果是否符合预期。此外,还要注意经纬度的范围,是否有可能输入的是负数(西经和南纬用负数表示),代码是否能正确处理。 然后是关于示例代码的结构。用户可能需要一个完整的函数,包含输入参数的转换,中间变量的计算,以及返回结果。示例代码中需要注意变量类型,使用double还是float,这取决于STM32的资源和精度需求。不过一般来说,使用double可能会有更高的精度,但占用更多内存,如果资源紧张,可以用float。 此外,代码中需要处理角度的转换,例如将度数转换为弧度,这部分需要乘以π/180。还需要计算sin和cos的值,这里要注意函数的参数单位是否正确。在C语言中,sin、cos等函数默认使用弧度,所以转换是必须的。 可能还需要提醒用户注意的地方有:输入参数的顺序是否正确,是否有可能输入的是字符串或者其他格式,是否需要做错误处理,比如经纬度是否在合理范围内(纬度-90到90,经度-180到180)。不过用户的问题中可能暂时不需要这些,但示例代码可以加上注释说明。 最后,应该提供完整的代码示例,并解释关键步骤。同时,在相关问题部分,可以引导用户了解更多关于Haversine的优化、其他距离计算方法,或者如何在资源受限环境下提高计算效率等。</think>在STM32平台上使用Haversine公式计算经纬度距离,可通过以下步骤实现: ### 一、Haversine公式原理 $$d = 2R \cdot \arcsin\left( \sqrt{\sin^2\left(\frac{\Delta\phi}{2}\right) + \cos\phi_1 \cos\phi_2 \sin^2\left(\frac{\Delta\lambda}{2}\right)} \right)$$ 其中: - $\phi$为纬度,$\lambda$为经度(需转换为弧度) - $R$为地球半径(平均6371km) - $\Delta\phi = \phi_2 - \phi_1$, $\Delta\lambda = \lambda_2 - \lambda_1$[^1] ### 二、STM32实现代码 ```c #include <math.h> #define EARTH_RADIUS 6371.0 // 单位:千米 #define DEG_TO_RAD 0.01745329251994329576923690768489 // π/180 double haversine_distance(double lat1, double lon1, double lat2, double lon2) { // 角度转弧度 lat1 *= DEG_TO_RAD; lon1 *= DEG_TO_RAD; lat2 *= DEG_TO_RAD; lon2 *= DEG_TO_RAD; // 经纬度差值 double dlat = lat2 - lat1; double dlon = lon2 - lon1; // Haversine公式计算 double a = sin(dlat/2) * sin(dlat/2) + cos(lat1) * cos(lat2) * sin(dlon/2) * sin(dlon/2); double c = 2 * atan2(sqrt(a), sqrt(1-a)); return EARTH_RADIUS * c; } ``` ### 三、关键实现说明 1. **浮点运优化**:STM32F4/F7系列支持硬件FPU,建议开启`-mfpu=fpv4-sp-d16`编译选项 2. **精度控制**:使用double类型可获得更高精度,在资源受限时可改用float类型 3. **数学库支持**:需在工程中链接`libm.a`数学库(gcc添加`-lm`编译参数)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值