We've made many mistakes applying arc tangent.
Math.atan2(y,x) = tan⁻¹ y/x with range -π to π
Often the surrounding code was tweaked to make results appear more right but not correct by the rules we intended. Even our isolated test cases has been revised repeatedly over days before we could explain every step to our satisfaction. github
// compute planar geometry with math conventions let dy = north*69.05 let dx = east*-48.99 let angle = Math.atan2(dy,dx) // into clockwise bering let bering = (90-angle*180/Math.PI+360)%360 // round to nearest octant let oct = Math.round(bering/45)%8
We start by adjusting for the spherical to planar approximation at 45 degree latitude. calc
Here we look for centerline markers for directions. We look to see that these are evenly space in radius and angle.
45.485912, -122.746232 0 ⇒ n 45.481671, -122.731798 45 ⇒ ne 45.471430, -122.725820 90 ⇒ e 45.461189, -122.731798 135 ⇒ se 45.456948, -122.746232 180 ⇒ s 45.461189, -122.760666 225 ⇒ sw 45.471430, -122.766644 270 ⇒ w 45.481671, -122.760666 315 ⇒ nw
Note, above we are choosing angles and computing lat/lon for the map. In Compass Rose we must run the calculation the other way so we give that a try.
► compute degrees north and east to trail
► compute distance in miles dy north and dx east
► compute radians +/- counter-clockwise from due east
► convert to degrees + clockwise from due north
► convert to fractional octants then round
► fold modulo 8 into octants 0 to 7
► index into labels [N, NE, E, SE, S, SW, W, NW]
See Places I Have Been where this Compass Rose first appeared in wiki and has now been brought into alignment with this analysis.