Bearings

Great circle on a sphere, proposed · checked against GeographicLib's GeodSolve

Preview

The test data isn't published yet; the work is in issue #3. The case count, the expiry date and everything under Test data are made up to show how the finished page will look.

Planned · 4 cases

What it is

A bearing is only meaningful with its north. A map has three: true north along the meridian, grid north along the map’s grid lines, and magnetic north where the compass points. Converting between them means adding or subtracting the angles between them, and the sign of each angle is where code goes wrong.

True north, grid north 5 degrees east of it, and magnetic north 20 degrees east of true, with grid convergence, the G-M angle and declination marked between them

Operations

OperationGives
inverse The distance and initial bearing between two pointsIn: fromLatitudeInDegrees, fromLongitudeInDegrees, toLatitudeInDegrees, toLongitudeInDegrees
Out: distanceInMeters, bearingInDegrees
destination The point at a distance and bearing from anotherIn: fromLatitudeInDegrees, fromLongitudeInDegrees, distanceInMeters, bearingInDegrees
Out: toLatitudeInDegrees, toLongitudeInDegrees
backAzimuth The reverse of a bearingIn: bearingInDegrees
Out: backAzimuthInDegrees
turn The shortest turn from one bearing to anotherIn: fromBearingInDegrees, toBearingInDegrees
Out: turnInDegrees, direction
convertNorth A bearing converted between true, magnetic and grid northIn: bearingInDegrees, fromNorth, toNorth, magneticDeclinationInDegrees, convergenceInDegrees
Out: convertedBearingInDegrees
formatBearing A bearing written in degrees or milsIn: bearingInDegrees, angleUnit
Out: bearingText
compassPoint The compass point nearest a bearingIn: bearingInDegrees, pointCount, style
Out: compassPointText

Fields

FieldMeaning
fromLatitudeInDegreesThe start, −90 to 90
fromLongitudeInDegreesThe start, −180 to 180
toLatitudeInDegreesThe end, −90 to 90
toLongitudeInDegreesThe end, −180 to 180
distanceInMetersAlong the great circle
bearingInDegrees0 to 360, clockwise from north
backAzimuthInDegreesThe bearing plus 180°, in 0 to 360
fromBearingInDegreesThe heading now
toBearingInDegreesThe heading wanted
turnInDegrees0 to 180
directionleft or right
fromNorthtrue, magnetic or grid
toNorthtrue, magnetic or grid
magneticDeclinationInDegreesTrue to magnetic, east positive, from the magnetic model
convergenceInDegreesTrue to grid, east positive, from UTM
convertedBearingInDegrees0 to 360
angleUnitdegrees, natoMils (6400), warsawPactMils (6000) or swedishMils (6300)
bearingText000° to 359°, or four-digit mils
pointCount4, 8, 16 or 32
styleabbreviation or words
compassPointTextLike NNE, NbE or north by east

Edge cases

CaseWhat's right
359.6°bearingText is 000°, never 360°. The same for mils.
A turn across north350° to 10° is 20° right, not 340° left
Every sign of declination and convergenceEach combination has a convertNorth case

For agents

Measure on a sphere of radius 6,371,008.8 m, not the ellipsoid, so distances match Turf and the map; this is proposed in issue #3. Normalize every bearing into [0°, 360°) after rounding, not before, so 359.6° writes as 000°. In convertNorth, take magneticDeclinationInDegrees and convergenceInDegrees east positive, with true = magnetic + declination and grid = true − convergence. Pass every case in vectors.json; text must match exactly.

Test data

In vectors.json, published 2026-01-01. Earth model: Sphere, radius 6,371,008.8 m (proposed). How to read it: Test data format.

FieldTolerance
distanceInMeters± 0.001
bearingInDegrees± 0.000001
toLatitudeInDegrees± 0.0000001
toLongitudeInDegrees± 0.0000001
backAzimuthInDegrees± 0.000001
turnInDegrees± 0.000001
convertedBearingInDegrees± 0.000001

Every other field is compared exactly.

CaseInputExpected
placeholder-1inverse · reference fromLatitudeInDegrees 11.11
fromLongitudeInDegrees 22.22
toLatitudeInDegrees 33.33
toLongitudeInDegrees 44.44
distanceInMeters 1234567.891
bearingInDegrees 12.345678
placeholder-2formatBearing · edge, hand bearingInDegrees 359.6
angleUnit "degrees"
bearingText "000°"
placeholder-3turn · edge, hand fromBearingInDegrees 350
toBearingInDegrees 10
turnInDegrees 20
direction "right"
placeholder-4compassPoint · hand bearingInDegrees 11.25
pointCount 32
style "words"
compassPointText "north by east"

Implementations

RepoStatus
gshaw/algorithms-swiftSwift Incomplete

Each is a public repo that runs this page's test data with mise run test. See how implementations work.

Source

Reference programGeodSolve, GeographicLib 2.7Charles Karney · MIT
DefinitionsMils and compass points, written from their definitionsCC0