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

短距离场景下Marker是否在Circle内的检测代码失效问题

解决短距离下Marker是否在Circle内的检测问题

原代码的问题出在短距离场景下的浮点精度误差:你用的球面距离公式依赖acos函数,当两点距离极近时,math.sin(lat1)*math.sin(lat2)+math.cos(lat1)*math.cos(lat2)*math.cos(lon2-lon1)的计算结果可能会因为浮点运算的微小误差超出[-1, 1]的有效范围(比如变成1.0000000001),导致acos返回NaN,最终距离计算错误,判断逻辑失效。

下面是两种可行的修复方案:

方案一:限制acos输入的有效范围

在计算前把acos的输入值钳制在[-1, 1]区间内,避免NaN问题:

import 'dart:math' as math;

double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
  double cosTheta = math.sin(lat1)*math.sin(lat2)+math.cos(lat1)*math.cos(lat2)*math.cos(lon2-lon1);
  // 处理浮点精度误差,确保值在acos的有效输入范围内
  cosTheta = math.max(-1.0, math.min(1.0, cosTheta));
  double distance = math.acos(cosTheta)*6371;
  return distance;
}

bool isMarkerInsideCircle(Marker marker, Circle circle) {
  double distanceBetweenPoints = calculateDistance(
    marker.position.latitude,
    marker.position.longitude,
    circle.center.latitude,
    circle.center.longitude,
  );
  
  // 注意检查单位一致性:如果circle.radius是米,这里要把distance转换成米(乘以1000)
  return distanceBetweenPoints <= circle.radius;
}

方案二:使用Haversine公式(短距离精度更稳定)

Haversine公式在短距离场景下的浮点精度表现更出色,不容易出现超出范围的问题:

import 'dart:math' as math;

double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
  final dLat = lat2 - lat1;
  final dLon = lon2 - lon1;
  
  final a = math.sin(dLat / 2) * math.sin(dLat / 2) +
            math.cos(lat1) * math.cos(lat2) *
            math.sin(dLon / 2) * math.sin(dLon / 2);
  final c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
  
  // 6371是地球半径(公里),如果circle.radius单位是米,替换为6371000
  final distance = 6371 * c;
  return distance;
}

bool isMarkerInsideCircle(Marker marker, Circle circle) {
  double distanceBetweenPoints = calculateDistance(
    marker.position.latitude,
    marker.position.longitude,
    circle.center.latitude,
    circle.center.longitude,
  );
  
  return distanceBetweenPoints <= circle.radius;
}

额外注意:务必确认circle.radius的单位和距离计算的单位一致——比如代码里默认计算的是公里,若你的Circle半径用的是米,需要把地球半径改成6371000,或者将计算出的距离乘以1000转换成米。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:38:14