【问题标题】:Java: Trigonometry and double inaccuracy causing NaNJava:三角函数和双重误差导致 NaN
【发布时间】:2011-04-20 03:10:57
【问题描述】:

我有一个使用纬度和经度的距离公式:

distance = EARTH_MILES_RADIUS
    * Math.acos(Math.sin(lat1 / RADIAN_CONV)
    * Math.sin(lat2 / RADIAN_CONV)
    + Math.cos(lat1 / RADIAN_CONV)
    * Math.cos(lat2 / RADIAN_CONV)
    * Math.cos((lng2 - lng1) / RADIAN_CONV));

lat1,lng1,lat2,lng2 是双原语。它们以双重原语的形式出现在我面前,对此我无能为力。

问题是,当我有一对相同的经度或纬度时,公式有时会返回 NaN。我相信这是因为我取的数字的反余弦值略大于 1,而实际上它应该正好是 1。如果这些点也是对映的,我可能会遇到问题,它们可能略小于 - 1.

我怎样才能最好地解决这个问题?

【问题讨论】:

  • 如果你想学习更好的Java大圆距离和方位计算实现,这里是UNICAR NETCDF库svn.unidata.ucar.edu/repos/common/java/trunk/src/main/java/ucar/…Copyright notice from UNICAR on NetCDF: These applications are copyrighted by UCAR and are intended to be freely available with very minimal restriction.
  • 重新格式化的代码;如果不正确,请恢复。
  • @eee 我在链接代码中看到他们有if ((lat1 == lat2) && (lon1 == lon2)) 在这种情况下距离设置为零,所以也许这是最好的解决方案。也许在一定精度内检查相等性是不必要的(puddingfox 的解决方案)。这是我在我的系统上尝试过的解决方案,效果很好,但我不确定它是否适用于所有情况。

标签: java floating-point geospatial trigonometry double-precision


【解决方案1】:

如果你确实像我想的那样计算大圆距离,你应该使用文森蒂公式而不是你所拥有的。

http://en.wikipedia.org/wiki/Great-circle_distance

【讨论】:

  • 文森蒂公式的表现不会更差吗?我正在处理大量数据。
  • 除非您尝试编写实时应用程序,否则我看不出这会是什么大问题。
  • 性能是个大问题,因为它是一个网站,而且距离通常很近(
  • 如果正确实施,T.Vincenty 公式的性能不是一个真正的问题......请参阅我在您的主要帖子下方关于它的 Java 实现的评论,它将 Vincenty 的方法与其他方法(Rainsford's + Helmert's elliptical条款)
【解决方案2】:

检查代码中两个非常接近(理想情况下相等)的值。例如:

boolean doubleApproxEqual(double a, double b) {
    double PRECISION = 0.000001;
    if (Math.abs(a-b) < PRECISION) //not sure what the name of the function is
                                   //cannot be bothered to check
        return true;
    return false;
}

如果你得到一个 True,做 cos(1.0) 或其他什么

【讨论】:

  • 就个人而言,我会使用return math.abs(a-b) &lt; PRECISION :-)
【解决方案3】:

只需检查相等性就足以解决我的问题:

if (lat1 == lat2 && lng1 == lng2) ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    • 2019-03-31
    相关资源
    最近更新 更多