feat(cam-geom): min_loop_gap front-collision primitive #134

Merged
patman merged 3 commits from patman/min-loop-gap into main 2026-08-24 02:25:44 +00:00 AGit
Owner

Island lane I-a. Closest-approach between contour loops (line/line, line/arc, arc/arc) with tangency-sweep proptests — the geometric primitive the coupled-front walk terminates on. Fixed from its original form to build standalone (a dangling re-export had made it red as its own PR). Opus review PASS.

Island lane I-a. Closest-approach between contour loops (line/line, line/arc, arc/arc) with tangency-sweep proptests — the geometric primitive the coupled-front walk terminates on. Fixed from its original form to build standalone (a dangling re-export had made it red as its own PR). Opus review PASS.
feat(cam-geom): min_loop_gap front-collision primitive
Some checks failed
CI / build-test (pull_request) Failing after 5s
1f90f79508
Adds `cam_geom::min_loop_gap(a, b) -> Result<Option<Length>, QueryError>`,
the one new geometric primitive the island-clearing design calls for
(docs/superpowers/island-clearing-design.md, step I-a / ID-5). `Some(gap)`
means the two closed loops are disjoint with exactly that clearance;
`None` means they touch or cross within tolerance — a merge event. This is
what lets the coupled outer/island walk (I-e) detect that an eroding outer
front and a dilating island front have met, without any boolean or
arrangement machinery, which cam-geom does not have and which the design
explicitly defers to v2 (ID-4, ID-13).

What it adds:

- `min_loop_gap`, an all-pairs segment sweep over the two loops, short
  circuiting to `None` on the first touching or crossing pair. Coplanarity
  is checked the way `StockState::plane` checks it (first-segment start Z,
  within the looser of the two loops' own tolerances), returning
  `QueryError::NotCoplanar` otherwise.
- `segment_gap` dispatching to three exact closed-form kernels:
  `line_line_gap` (parametric crossing test padded by tol relative to each
  segment's own length, then the four-endpoint clamped-projection minimum),
  `line_arc_gap` (circle-vs-line hits filtered to the arc's own sweep, plus
  a perpendicular-foot interior candidate), and `arc_arc_gap` (circle-vs-arc
  hits filtered to both sweeps, plus the two-circle center-to-center
  interior candidate covering both externally-separate and nested pairs).

Everything is built from the existing `circle_segment_intersections` and
`distance_to_segment` — no new solver, no iteration, no new dependency —
and reuses `circle_segment_intersections`'s own skip/tolerance semantics so
grazing tangency is classified consistently with the rest of the module.

Invariants: symmetric in its arguments; translation invariant; a returned
gap is a true lower bound on the distance between any point of `a` and any
point of `b` (never over-reports clearance, which is the direction that
matters for collision safety); interior-interior minimizers are found, not
just vertex ones, so a nested-circle or off-axis square/circle pair reads
exact rather than endpoint-approximate.

Two documented limitations, both stated on the function: the two-circle
interior candidate is skipped for a concentric arc pair (no center-to-center
direction), where the endpoint fallback is nonetheless exact and returns
|r2 - r1|; and the line-line crossing test uses an absolute denominator
epsilon rather than a length-scaled one, so a near-parallel crossing could
in principle fall through to the endpoint estimate — finite and safe, just
not provably tight, and not reachable from the offset-loop shapes cam-clear
produces.

Tests: exact-value unit tests for disjoint squares, disjoint circles,
nested circles, and an off-axis square/circle pair; `None` for touching and
for crossing shapes; `NotCoplanar` for mixed planes; a swept circle pair
whose Some -> None transition lands within tol of true tangency; and
proptests for symmetry, translation invariance, and the bound-vs-sampled
-distance property on both general and arc-heavy (wedge) loop pairs,
including concentric and near-concentric wedges to cover the documented
degenerate branch.

Co-authored-by: patman-assist <patrick-ai@kgroo.co>
chore: normalize comments
Some checks failed
CI / build-test (pull_request) Failing after 6s
08a59c9ef3
Co-authored-by: patman-assist <patrick-ai@kgroo.co>
style: rustfmt --edition 2024 drift fix
All checks were successful
CI / build-test (pull_request) Successful in 8m37s
a36b8270d8
Reformats files that predate the runner's current rustfmt; no code changes.

Co-authored-by: patman-assist <patrick-ai@kgroo.co>
patman merged commit 4f49177c36 into main 2026-08-24 02:25:44 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
patman/KGROO!134
No description provided.