问题
double computeHeading(double latitude1, double longitude1, double latitude2, double longitude2)
{
double degToRad = PI / 180.0;
double phi1 = latitude1*degToRad;
double phi2 = latitude2*degToRad;
double lam1 = longitude1*degToRad;
double lam2 = longitude2*degToRad;
double x,y;
x = cos(phi2) * sin(lam2-lam1);
printf("X is %lf\n", x);
y = cos(phi1) * sin(phi2) - sin(phi1) * cos(phi2) * cos(lam2-lam1);
printf("Y is %lf\n", y);
return atan2(x,y)*180/PI;
}
I am using the above function to determine the true bearing from North between two geographic coordinates.
I'm currently developing a small navigation widget which uses GPS data from Android sensors. The widget has an arrow facing towards a point away from the device's current location. The arrow's direction changes with the device's current location and azimuth to always face the distant point.
Here is a scenario:
I'm at a location, facing north, and another location has a bearing of 300 degrees(somewhat northwest of me). If I face towards south, without moving, my relative bearing to the distant location should be 120 degrees.
How can I find the relative bearing with accounting for the facing direction (azimuth)?
回答1:
There are a couple of ways you can work this out. The first, which is what you appear to be doing, assumes the earth is spherical. Relative bearings are calculated using Haversine formulation for great circle navigation. Given starting and ending points, this formulation finds the great circle passing through the two points. From this an initial bearing can be calculated. This great circle route is the shortest route between the two points, but suffers from the problem the bearing, in general, will not be constant along the route. Also, except under some very specific cases, the reverse bearing does not behave as you seem to expect and if you want to determine it in general, you will have to perform another calculation reversing the starting and ending points.
Another method you could use is the Rhumb line formulation. In this case, the bearing between the starting point and ending point is constant and would allow you to use the relation you have for the reverse course if you would like. Since this will in general differ from the great circle distance, following Rhumb lines will not result in the shortest path between the two points, but it does simplify the navigation by holding the course constant.
Both of these approaches are described in detail at Calculate distance, bearing and more between Latitude/Longitude points
Another formulation for great circle navigation which uses a more accurate representation of the earth's shape, an oblate spheriod, which is a special type of ellipsoid, is attributed to Vincenty with additional enhancements provided by Karney. In these cases, the formulation is quite a bit more complicated and is probably overkill for most applications, and performance is quite a bit worse than the Haversine formulations above. But these formulations provide much better accuracy if you need it.
Update:
Based on the comment below, the main issue is one of figuring out how far to turn. This will simply be the angle between the normals of the plane containing the great circles for the current heading and the desired heading. To get the normal for the plane on the current heading, you need your current location L
and a point some distance away on the current heading, C
. The normal is just V = L×C
. To compute the normal for the plane containing the great circle along the desired heading, you only need to know a point along the desired route, which you already have in the form of your destination point, which we call D
. You can then find the normal by U = L×D
. The angle between them is given by θ = acos((U∙V)/(|U||V|))
.
In order to find L
, C
and D
you must convert the Latitude, Longitude, Altitude (LLA) coordinates into Earth Centered, Earth Fixed (ECEF) coordinates.
来源:https://stackoverflow.com/questions/33989893/how-do-you-find-relative-bearing-between-two-points