The problem is indicated by the word "well-conditioned." It's an issue of computer arithmetic, not mathematics.
Here are the basic facts to consider:
One radian on the earth spans almost 10^7 meters.
The cosine function for arguments x near 0 is approximately equal to 1 - x^2/2.
Double-precision floating point has about 15 decimal digits of precision.
Points (2) and (3) imply that when x is around one meter, or 10^-7 radians (point 1), almost all precision is lost: 1 - (10^-7)^2 = 1 - 10^-14 is a calculation in which the first 14 of the 15 significant digits all cancel, leaving just one digit to represent the result. Flipping this around (which is what the inverse cosine, "acos", does) means that computing acos for angles that correspond to meter-length distances cannot be done with any meaningful accuracy. (In certain bad cases the loss of precision gives a value where acos is not even defined, so the code will break down and give no answer, a nonsense answer, or crash the machine.) Similar considerations suggest you should avoid using the inverse cosine if distances less than a few hundred meters are involved, depending on how much precision you're willing to lose.
The role played by acos in the naive law-of-cosines formula is to convert an angle to a distance. That role is played by atan2 in the haversine formula. The tangent of a small angle x is approximately equal to x itself. Consequently the inverse tangent of a number, being approximately that number, is computed essentially with no loss in precision. This is why the haversine formula, although mathematically equivalent to the law of cosines formula, is far superior for small distances (on the order of 1 meter or less).
Here is a comparison of the two formulas using 100 random point-pairs on the globe (using Mathematica's double-precision calculations).
You can see that for distances less than about 0.5 meters, the two formulas diverge. Above 0.5 meters they tend to agree. To show how closely they agree, the next plot shows the ratios of the law of cosines:haversine results for another 100 random point pairs, with their latitudes and longitudes randomly differing by up to 5 meters.
This shows that the law of cosines formula is good to 3-4 decimal places once the distance exceeds 5-10 meters. The number of decimal places of accuracy increases quadratically; thus at 50-100 meters (one order of magnitude) you get 5-6 dp accuracy (two orders of magnitude); at 500-1000 meters you get 7-8 dp, etc.
You don't have quite enough information, because there are two solutions. You need to specify whether you are traversing the circle positively or negatively. I will discuss the positive (counterclockwise) case; the negative case is computed in the same way with obvious changes.
For the positive direction, the circle's center is to the left of the arc. Just add 90 degrees to the bearing and travel for the radial distance and stop: that's the center. Now we know the circle's center and radius, we can find any point on it. The bearing from the center to a point on the circle is 90 degrees less than the bearing around the circle (in the positive direction).
Here are some formulas. The start point has coordinates (x1,x2), the radius is r, and the bearing is alpha. (I use the mathematical convention that 0 is due east, 90 is north.) We seek the coordinates (y1,y2) of the endpoint where the new bearing will be beta. Let the origin's coordinates be (o1,o2).
The direction vector for bearing alpha is (by definition)
(cos(alpha), sin(alpha))
Rotating this 90 degrees to the left gives the unit vector
(-sin(alpha), cos(alpha))
Moving along this from (x0,x1) by distance r ends up at
(o1,o2) = (x1,x2) + r * (-sin(alpha), cos(alpha))
That's the circle's center.
The bearing from the center to the end point is beta - 90 degrees. The endpoint is reached by moving a distance r in this direction, whence
(y1,y2) = (o1,o2) + r * (cos(beta-90), sin(beta-90))
That's it.
Here is an animation for the start point (x1,x2) = (1000, 2000), shown in red, and the radius r = 4000. The end point (y1,y2) is shown in red. Their bearings are indicated by arrows tangent to the circles. It begins with start and stop bearings at 0 (due east) and increases the stop bearing until it reaches 360. (During this time, because the start bearing is fixed, the circle centers--shown as little black dots--do not change.) Then it increases the start bearing until it, too, reaches 360. (During this time, because the start bearing is changing, the circle centers are moving accordingly.) Both solutions are shown simultaneously: the positive direction and the negative direction.
Best Answer
This is basically the same thing I said here, just modified to produce the end point instead of a line:
Where
start_points
is the table containing your starting points,the_geom
in that table is the geometry column,dist_field
is the distance field andbearing_field
is the bearing field.You may need to change the direction of the initial line (
ST_MakePoint(-1 * dist_field,0.0)
) to vertical (swap the coordinates/field name) depending on how you are measuring your bearing.