Why is this bearing calculation so inacurate?
Asked Answered
L

3

10

Is it even that inaccurate? I re-implented the whole thing with Apfloat arbitrary precision and it made no difference which I should have known to start with!!

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);
 }

The first assertion in the test gives this:

java.lang.AssertionError: expected:<270.0> but was:<270.29389750911355>

0.29 seems to quite a long way off? Is this the formula i chose to implement?

Lessard answered 9/2, 2010 at 22:11 Comment(3)
Are you using arbitrary-precision trig?Deese
can you add toRadians and toDegrees?Min
Using the java.lang.Math trig function and import static java.lang.Math.toDegrees; import static java.lang.Math.toRadians;Lessard
K
17

If you've done what you seem to have done and done it correctly you have figured out the bearing of A from B along the shortest route from A to B which, on the surface of the spherical (ish) Earth is the arc of the great circle between A and B, NOT the arc of the line of latitude between A and B.

Mathematica's geodetic functions give the bearings, for your test positions, as 89.7061 and 270.294.

So, it looks as if (a) your calculation is correct but (b) your navigational skills need polishing up.

Kilbride answered 9/2, 2010 at 22:35 Comment(3)
Quite right. Change the test parameters to 0.0 degrees latitude and the test passes.Culex
You are right about (b) let me give an example to cement my understanding. If I wanted to walk from Paris (48, -2) to Munich (48, -11) I would not walk due east but at a bearing of 86.652 degrees. This makes sense more if you think about walking from somewhere the uk to greenland, you would not follow a line parallel to a line of latitude (are lines of latitude parallel??).Lessard
Well, you would start walking along that bearing (forget about roads, and obstacles) but you would then constantly have to adjust your bearing as you walked; great-circle routes do not (generally) follow a line of constant bearing (or loxodrome). But things are starting to get complicated, break out Bowditch.Kilbride
W
1

java.lang.AssertionError: expected:<270.0> but was:<270.29389750911355>

This 0.29 absolute error represents a relative error of 0.1%. How is this "a long way off"?

Floats will give 7 significant digits; doubles are good for 16. Could be the trig functions or the degrees to radians conversion.

Formula looks right, if this source is to be believed.

If I plug your start and final values into that page, the result that they report is 089°42′22″. If I subtract your result from 360 and convert to degrees, minutes, and seconds your result is identical to theirs. Either you're both correct or you're both wrong.

Waxen answered 9/2, 2010 at 22:24 Comment(1)
If this is due to numeric error it is a long way off for such a simple calculation.Colner
C
1

Are you sure this is due to numeric problems? I must admit, that I don't exactly know what you are trying to calculate, but when you are dealing with angles on a sphere, I'd expect small deviations from what you would expect in euclidian geometry.

Colner answered 9/2, 2010 at 22:27 Comment(1)
And sometimes large deviations too.Kilbride

© 2022 - 2024 — McMap. All rights reserved.