Skip to content

feat(g.Line): add isCollinear() and use it in the jumpover connector - #3503

Open
kumilingus wants to merge 3 commits into
clientIO:devfrom
kumilingus:feat/line-is-collinear
Open

feat(g.Line): add isCollinear() and use it in the jumpover connector#3503
kumilingus wants to merge 3 commits into
clientIO:devfrom
kumilingus:feat/line-is-collinear

Conversation

@kumilingus

Copy link
Copy Markdown
Contributor

Summary

  • g.Line#isCollinear(line)true when all four endpoints lie on one infinite line. Same exact cross() === 0 test as containsPoint() / equals(); evaluated in both directions so a zero-length line does not pass trivially (a point off the line → false, two points → true).

  • Jumpover connector — replaces the private helpers added in fix(connectors.Jumpover): stacked links causing jumps #2255:

    • overlapExists() was a bounding-box overlap test, so crossing/perpendicular lines counted as "overlapping" too.
    • sortPointsAscending() could undo its own x-sort for non-axis-aligned lines (e.g. (10,5)-(0,20)).

    The call site becomes thisLine.isCollinear(line) && thisLine.containsPoint(line.end) — collinear + ends on the link is exactly the stacked-links condition. Behaviour change: a perpendicular segment that merely ends on the link (T-junction) no longer causes the following segment to be skipped; that skip was an accident of the bbox test.

  • g.intersection.exists(line, line) intentionally left unchanged (still false for collinear overlap).

Changesets: minor for g.Line, patch for connectors.Jumpover.

Test plan

  • karma:geometry — 353/353; new isCollinear(line) module (partial overlap, containment, identical, reversed, touching, disjoint collinear, diagonal, parallel offset, crossing, perpendicular T-junction, shared endpoint only, zero-length on/off line in both call orders). Watched failing first (isCollinear is not a function).
  • karma:joint — 2113/2113, incl. jumpover connector - stacked links do not cause jumps.
  • grunt test:ts
  • eslint on all touched files

🤖 Generated with Claude Code

`isCollinear(line)` is true when all four endpoints lie on one infinite
line. It uses the same exact cross-product test as `containsPoint()`
and is checked in both directions so a zero-length line does not pass
trivially.

The jumpover connector's private `overlapExists()` was a bounding-box
test (true for crossing lines too) and `sortPointsAscending()` could
undo its own x-sort for non-axis-aligned lines. Both are replaced by
`thisLine.isCollinear(line) && thisLine.containsPoint(line.end)`, which
is what the stacked-links fix (clientIO#2255) actually needs. A perpendicular
segment that merely ends on the link no longer causes the following
segment to be skipped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
kumilingus and others added 2 commits September 12, 2026 11:46
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

1 participant