From cc02e76bb436a32a8d62ee6fcd21666c81b2c1a8 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Mon, 20 Apr 2026 17:22:10 -0400 Subject: [PATCH] Make `_contains(::SphericalCap, ::SphericalCap)` inclusive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change `<` to `<=` so that an internally-tangent small cap counts as contained. Matches the convention of the sibling `_contains(::SphericalCap, ::UnitSphericalPoint)` method one line below (which uses `<=` for a point exactly on the cap boundary) and S2's `S2Cap::Contains(const S2Cap&)`. The pre-existing `@test_broken` in `test/utils/unitspherical.jl` exercised exactly this boundary case: big_cap = hemisphere centered at (1,0,0), small_cap centered at (1/√2, 1/√2, 0) with radius π/4. `dist(centers) = π/4` and `small.radius + dist = π/2 = big.radius` exactly. Flip the tripwire to `@test`. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/utils/UnitSpherical/cap.jl | 6 ++++-- test/utils/unitspherical.jl | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/utils/UnitSpherical/cap.jl b/src/utils/UnitSpherical/cap.jl index 82c4e9ad6..483ddebdb 100644 --- a/src/utils/UnitSpherical/cap.jl +++ b/src/utils/UnitSpherical/cap.jl @@ -104,8 +104,10 @@ _disjoint(x::SphericalCap, y::SphericalCap) = !_intersects(x, y) function _contains(big::SphericalCap, small::SphericalCap) dist = spherical_distance(big.point, small.point) - # small circle fits in big circle - return dist + small.radius < big.radius + # small circle fits in big circle; `<=` so internally-tangent small + # caps count as contained, matching the point overload below and + # S2's `S2Cap::Contains(const S2Cap&)` convention. + return dist + small.radius <= big.radius end function _contains(cap::SphericalCap, point::UnitSphericalPoint) spherical_distance(cap.point, point) <= cap.radius diff --git a/test/utils/unitspherical.jl b/test/utils/unitspherical.jl index 620fdfcc9..37f84895b 100644 --- a/test/utils/unitspherical.jl +++ b/test/utils/unitspherical.jl @@ -117,7 +117,7 @@ end # Test containment big_cap = SphericalCap(UnitSphericalPoint(1.0, 0.0, 0.0), π/2) small_cap = SphericalCap(UnitSphericalPoint(1/√2, 1/√2, 0.0), π/4) - @test_broken UnitSpherical._contains(big_cap, small_cap) + @test UnitSpherical._contains(big_cap, small_cap) @test !UnitSpherical._contains(small_cap, big_cap) end