Skip to content

h3: clamp the haversine term so antipodal distances are not NaN - #178

Merged
justinhwang merged 1 commit into
masterfrom
fix/antipodal-distance
Oct 27, 2026
Merged

justinhwang merged 1 commit into
masterfrom
fix/antipodal-distance

Conversation

@justinhwang

Copy link
Copy Markdown
Collaborator

Summary

GreatCircleDistanceRads, GreatCircleDistanceKm and GreatCircleDistanceM returned NaN for some antipodal pairs. Rounding pushes the haversine term just above its mathematical maximum of 1, and sqrt(1 - h) is then NaN. For example (10.123456789, 20.987654321) against its antipode. The fix clamps the term at 1, which affects only that overshoot. This is upstream uber/h3#1267.

The conformance suite is unaffected: its distance sampler already redraws far targets within 1e-3 radians of antipodal, where the haversine is ill-conditioned, so no patch or regeneration is needed.

The test helper assertRelClose compared with >, and every comparison against NaN is false, so a NaN result passed it. It now rejects NaN explicitly. The new antipodal case in TestGreatCircleDistance fails without the clamp and passes with it.

Test plan

  • TestGreatCircleDistance/antipodal fails with the clamp removed (rads = NaN) and passes with it
  • go test -race ./... green, root and conformance
  • golangci-lint run ./... clean

For some antipodal pairs rounding pushes the haversine term just above
its mathematical maximum of 1, and sqrt(1 - h) is then NaN, so
GreatCircleDistanceRads and the kilometre and metre forms returned NaN
instead of pi times the radius. Clamping the term at 1 affects only that
overshoot. This is upstream uber/h3#1267. The conformance suite is
unaffected: its distance sampler already redraws far targets within 1e-3
radians of antipodal, where the haversine is ill-conditioned.

The test helper assertRelClose compared with >, and every comparison
against NaN is false, so a NaN result passed; it now rejects NaN, and the
new antipodal case fails without the clamp.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 40544249803

Coverage remained the same at 100.0%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: 4 of 4 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 3673
Covered Lines: 3673
Line Coverage: 100.0%
Coverage Strength: 5166667.48 hits per line

💛 - Coveralls

@justinhwang
justinhwang merged commit 618a1d4 into master Oct 27, 2026
15 checks passed
@justinhwang
justinhwang deleted the fix/antipodal-distance branch October 27, 2026 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants