Repository navigation
Coverage: corner passes and near-coincident edges (#25); exact approx centre ties - #36
Merged
Merged
Conversation
… centre ties An edge exactly through a cell corner, or two nearly coincident edges, overcounted a cell by up to a whole cell. Three fixes in walk_polyline and walk_ring, plus one in the approx sweep: - Corner guard. An edge through a corner gave a crossing an ulp off the corner and a sliver traversal along the next cell's wall where the ring only touches the corner. The walker now snaps an exit crossing within the lattice tolerance (1e-9 of a cell) of a corner onto the corner. - Green's theorem for cells crossed by several traversals, and for a single traversal lying along the cell walls. exactextract's chain chaser depends on the order of the traversal ends around the cell; rounding can swap two nearly coincident ends (a sliver, a ring doubling back along itself) and it then returned the complement. Each traversal now adds the integral of (x - xmax) dy, plus the cell width times the covered length of the left wall, which is minus the net height of the ring's traversals left of the cell in its row. Same identity as controlledburn-rs's CoverageWindow. - A coverage below the sweep's 1e-6 tolerance gets a record only when the ring passes through the cell: a spike to a corner vertex and back left 1e-16, and that record blanked a fully covered cell. - Approx: the side of a cell centre an edge passes is an exact orientation test (FMA-split products summed as a Shewchuk expansion) on the edge's endpoints taken bottom to top. Intercepts sort by column, side, then x. Before: the issue's ring covered 6.6016 for 6.1578 (cell (12, 18) burned 1.0 for 0.0943); a 4e-13 sliver covered 11 cells at 2x resolution; the bowtie probe covered 26 cells of 32. After: all exact. Golden tables dumped from this build match controlledburn-rs's (bit for bit) except bowtie coverage, which gains the six missing cells, and the record order of lines_multi, which already differed on main. Same change as controlledburn-rs (fix/corner-pass). Tests: C++ test_corner_pass and four more (124 failed checks before the fix), R test-lattice-snap.R, Python test_regressions.py, and the shared fixture corner_pass (14 fixtures, synced with controlledburn-rs). ctest 2/2, R 384 expectations passed, pytest 133 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
R parses 17-digit decimal literals with its own strtod, which is an ulp off where long double is double (macOS arm64). This test's edges pass 1e-13 from a centre, so the ulp moved them across it and all 16 start variants failed there. Hex literals parse exactly on every platform. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #25, the C++ side of hypertidy/controlledburn-rs#6. Same change as hypertidy/controlledburn-rs#18.
Before: a cell was overcounted where a polygon edge passes exactly through a cell corner, or where two edges nearly coincide. #25's ring covered 6.6016 for an area of 6.1578 (cell (12, 18) burned 1.0, exact 0.0943). The other rings from controlledburn-rs#6 burned 0.739 for 0.455 and 0.839 or 1.0 (depending on the start vertex) for 0.339. A sliver of area 4e-13 covered 11 whole cells at 2x resolution. In approx mode, an empty cell burned when two edges both passed 1e-13 right of its centre.
Causes:
left_hand_areadepends on the order of the traversal ends around a cell. Rounding can swap two nearly coincident ends (that sliver, or a ring doubling back along itself), and it then returns the complement.After:
CoverageWindow. Each traversal adds its integral of (x - xmax) dy, plus the cell width times the covered length of the left wall, read from the ring's traversals to its left in the row. No ordering is involved.Golden tables (
controlledburn-golden.jsonlives in controlledburn-rs; dumped from this build): the 28 existing cases match bit for bit, exceptbowtiecoverage. Its closing edge lies on a column wall, and it gains the six cells it was missing: 26 cells before, the exact 32 now.lines_multi's line records come out in a different order from the golden file, as they already do on main. Three cases are added:corner_pass,sliver_coincident_edgesandapprox_centre_tie.corner_passis also a new shared fixture (14 now); the CSVs are byte-identical between the repos.How checked:
test_burnadds five tests, which fail 124 checks on main.test-lattice-snap.Radds four tests).test_regressions.pyadds four).mainfailed 20 of 20 at 100,000.Status of the other ports (wxylib m20): the hole fix (controlledburn-rs#11, here #27/#31) and the wall-cell fix (#29 and 1a597eb, via #32) are both already on main, and Rust and C++ agree on their golden tables.
CoverageWindow/RowPrefixdon't exist in the C++ core yet; this PR doesn't port them.Also noticed: NEWS.md doesn't mention the hole or wall-cell fixes, though 0.3.2 contains both. Not changed here. DESCRIPTION goes to 0.3.2.9000 for the development NEWS entry.
🤖 Generated with Claude Code