为什么这个轴承计算如此不准确?

10

它真的那么不准确吗?我用Apfloat任意精度重新实现了整个东西,但没有任何改善,这本来应该是我一开始就知道的!!

public static double bearing(LatLng latLng1, LatLng latLng2) {
 double deltaLong = toRadians(latLng2.longitude - latLng1.longitude);

 double lat1 = toRadians(latLng1.latitude);
 double lat2 = toRadians(latLng2.latitude);

 double y = sin(deltaLong) * cos(lat2);
 double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
 double result = toDegrees(atan2(y, x));
 return (result + 360.0) % 360.0;
}

@Test
 public void testBearing() {

  LatLng first = new LatLng(36.0, 174.0);
  LatLng second = new LatLng(36.0, 175.0);
  assertEquals(270.0, LatLng.bearing(second, first), 0.005);
  assertEquals(90.0, LatLng.bearing(first, second), 0.005);
 }

测试中的第一个断言给出了以下结果:

java.lang.AssertionError: 预期值为:<270.0>,但实际值为:<270.29389750911355>

0.29看起来相差很远?这是我选择实现的公式吗?


你是否正在使用任意精度三角函数? - Anon.
你能添加 toRadians 和 toDegrees 吗? - Ron
使用java.lang.Math三角函数和 import static java.lang.Math.toDegrees; import static java.lang.Math.toRadians; - Greg
3个回答

17
如果您已经完成了你似乎完成并且正确完成的工作,则可以确定从A到B的最短路径上A相对于B的方位,这在球面(或类球体)地球的表面上是A和B之间大圆弧线路,而不是A和B之间纬线弧线路。Mathematica的测地功能为您的测试位置提供方位角,分别为89.7061270.294。因此,看起来你的计算是正确的,但你的导航技能需要提高。

完全正确。将测试参数更改为0.0度纬度,测试就通过了。 - Bill the Lizard
你对(b)的理解是正确的,让我举个例子来加深我的理解。如果我想从巴黎(48, -2)走到慕尼黑(48, -11),我不会向东走,而是以86.652度的方位角行走。如果你考虑从英国某处走到格陵兰岛,这更有意义,你不会沿着纬线平行的线路走(纬线是平行的吗?)。 - Greg
2
好的,你将沿着这个方位开始行走(忘记道路和障碍物),但是你需要不断调整方位才能前进;大圆航线不会(通常)遵循恒定方位线(或罗盘航线)。 但现在事情开始变得复杂了,可以查看 Bowditch。 - High Performance Mark

1
java.lang.AssertionError: 期望值为:270.0,但实际值为:270.29389750911355。
这个 0.29 的绝对误差相当于相对误差的 0.1%。这怎么能说是“相差甚远”呢?
浮点数只能提供 7 位有效数字,双精度浮点数则可提供 16 位。可能是三角函数或角度转弧度的问题。
如果 this source 是正确的,那么公式就是正确的。
如果我将你的起始值和最终值输入到该网页,他们报告的结果是089°42′22″。如果我从 360 中减去你的结果,并将其转换为度、分和秒,你的结果与他们的结果完全相同。要么你们两个都是正确的,要么你们两个都是错误的。

2
如果这是由于数值误差造成的,那么对于这样一个简单的计算来说,这相距甚远。 - Jens Schauder

1

你确定这是由于数字问题吗?我必须承认,我不完全知道你试图计算什么,但当你处理球面上的角度时,会出现与欧几里得几何预期有所偏差的情况。


2
有时候也会出现较大的偏差。 - High Performance Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接