Skip to content

fix: CIRCULARSTRING(A,B,C,A) is a valid geometry (annulus) - #120

Merged
grootstebozewolf merged 2 commits into
feature/sfa-curve-rgrfrom
cursor/cs-abca-valid-ccfa
Aug 23, 2026
Merged

fix: CIRCULARSTRING(A,B,C,A) is a valid geometry (annulus)#120
grootstebozewolf merged 2 commits into
feature/sfa-curve-rgrfrom
cursor/cs-abca-valid-ccfa

Conversation

@grootstebozewolf

@grootstebozewolf grootstebozewolf commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Fixes V-CS leftover after #86/#87.

topic: curve
claimId: V-CS
witness: circularstring-abca
macro: V-CS
lane: validity
chunk: closed-4
issue: #86

Catalogued slice

TRIAGE / EPIC Phase 2 V-CS (CircularString validity / simplicity).
#87 already made the 3-click shell CIRCULARSTRING(A,B,C,A) a full
circumcircle (draw / length / disc kit). This pin is isValid / parse
acceptance
of that 4-control form, plus the concentric pair as a
valid annulus. ISO/IEC 13249-3. No DOI.

Not #114 / tb-h-1 paint (PRs #118 / #119, HOLD UX SIGN). Not complementary
sweep-mid for major-arc holes. Not H-CC area 50 + 12.5 acos(0.6).
Not 67-c / S15l / Touches-vs-Share. Not NTS. Not GEOS.

Observed

ISO/SFA wants an odd CircularString control count (3, 5, …).
CIRCULARSTRING(A,B,C,A) is 4 points: first arc A–B–C, then C–A has no
stored mid. WKTCircularStringTest.testRejectsEvenPointCount treated
every 4-point string as parse-invalid. After #87 the closed 4-control
form is a first-class full circle; GeometryCombiner already accepted
it, but CircularString.isValid() and CurveWKTReader did not.

Expected

  • CIRCULARSTRING(-5 0, 0 5, 5 0, -5 0) parses, stays CircularString,
    4 controls, first=last, isValid() == true.
  • Open leftover CIRCULARSTRING(0 0, 1 1, 2 0, 3 1) still fails parse
    and isValid().
  • Odd count ≥ 3 unchanged (still valid).
  • Concentric pair
    CURVEPOLYGON (CIRCULARSTRING(-5 0, 0 5, 5 0, -5 0), CIRCULARSTRING(-3 0, 0 3, 3 0, -3 0))
    is a valid annulus (shell + hole, both 4-control). WKT is not rewritten;
    no invented 5th control.

Change

  • CircularString.isValidControlCount / isValid: empty or odd ≥ 3, or
    closed 4-control with a circumcircle (threePointCircleCloseMid).
  • CurveWKTReader.readCircularStringText uses the same predicate
    (constructor still allows an invalid object; parse rejects open even).
  • Tests: CircularStringValidTest, WKTCircularStringTest accept closed-4.
  • README: odd-count rule is now enforced, with the [visual-qa] 3-click CurvePolygon circle is CIRCULARSTRING(A,B,C,A) but draws a closing line #86 exception named.

Tests (local)

mvn -pl modules/curve -Dcheckstyle.skip=true -Dpmd.skip=true \
  -Dtest=CircularStringValidTest,WKTCircularStringTest,CurveShapeWriterCurvePolygonTest,CircularDiscOverlayTest,CurveAwarenessGreenMetersTest test
# 69 tests, 0 failures
mvn -pl modules/curve -Dcheckstyle.skip=true -Dpmd.skip=true \
  -Dtest=WKT*Test,CircularStringToLinearTest test
# 73 tests, 0 failures

Checks

Checks: 4/4 green @ fce5d93

Merged to feature/sfa-curve-rgr by grootstebozewolf at 2026-08-23T05:26:22Z (1e446de7). Merge-in only; V-CS blobs unchanged from 2b56b1a4. NTS #19 / Proofs locationtech#532 do not need a SHA remint.

Open in Web Open in Cursor 

ISO/IEC 13249-3 wants an odd control count. Closed four-control
CIRCULARSTRING(A,B,C,A) is the #86 full-circle exception: complementary
close is implicit, no leftover mid. Open even leftover still fails parse
and isValid. A concentric pair of those rings is a valid annulus.

topic: curve
claimId: V-CS
witness: circularstring-abca
macro: V-CS
lane: validity
chunk: closed-4
issue: #86

Co-authored-by: jbloemscheer <jbloemscheer@gmail.com>
@grootstebozewolf
grootstebozewolf merged commit 1e446de into feature/sfa-curve-rgr Aug 23, 2026
4 checks passed
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