Skip to content

Conversation

@kunstewi
Copy link

@kunstewi kunstewi commented Oct 28, 2025

Currently working on this to make the testcases work and improve the logic, no need of review as of now, Thanks.

High-level

  • Replaced naive alternating offsets with a crossing-minimizing search that tries sign combinations for N≤6 overlapping groups, simulates geometry-preserving shifts, scores by total crossings, prunes early, and applies the best configuration. Falls back to the original alternating scheme when brute-force is not used or time-limited.
  • Added lightweight, inline orthogonal intersection/crossing utilities used for scoring.
  • Kept existing jog and cleanup behavior; visualization remained unchanged.
  • Added a focused unit test to cover multi-trace overlaps.

Detailed, review-friendly notes

  • Imports and type/style harmonization

    • Added semicolons and consistent TS style across TraceOverlapIssueSolver.ts to match project preferences; no functional impact.
  • Core algorithm replacement in _step()

    • Old behavior:
      • Computed offsets with an alternating pattern:
        • Magnitude: (floor(idx/2)+1) * SHIFT_DISTANCE
        • Sign alternated deterministically - + - + ... regardless of resulting crossings.
      • Applied offsets directly to correctedTraceMap.
    • New behavior:
      • Preserved the magnitude schedule exactly as before: (floor(idx/2)+1) * SHIFT_DISTANCE per overlapping group.
      • Introduced a sign search for N≤6 overlapping groups:
        • Enumerates all 2^N sign patterns, where bit i represents ± for group i.
        • Time-bounded with a short limit to keep UI snappy (30 ms guard).
        • Early-exit if a 0-crossing configuration is found.
        • Maintains a best-so-far score and prunes candidates whose partial score already exceeds the current best.
      • If N>6 or time limit reached, falls back to the original alternating scheme.
      • After choosing the best offsets, performs the real application (with jogs and cleanup) and writes the results into correctedTraceMap.
  • Inline helpers added to _step() for simulation/scoring (orthogonal-only)

    • orthogonalSegmentsIntersect(a1,a2,b1,b2): boolean
      • Handles only orthogonal segments:
        • Vertical vs horizontal and vice versa: point-crossing test with range checks.
        • Vertical vs vertical (same x) and horizontal vs horizontal (same y): interior overlap test counts as an intersection.
      • Ignores non-orthogonal cases (should not occur in our geometry).
    • countCrossingsBetweenPaths(pathA, pathB): number
      • Two nested loops over segments, uses orthogonalSegmentsIntersect.
      • Counts all intersections, including collinear overlaps and interior crossings.
    • Rationale: Keep them scoped and lightweight; no external dependency needed, supports the scoring function.
  • Simulation flow for scoring candidates

    • applyOffsetsToMap(offsets):
      • Builds a temporary map of corrected paths for the groups under consideration.
      • For each group:
        • Gathers unique segments per path (so a path with multiple overlaps is updated consistently).
        • Clones the path points to avoid mutating original state.
        • Applies offsets to only the overlapping segments:
          • For terminal segments (segment index 0 or last): calls existing applyJogToTerminalSegment to preserve endpoint orthogonality via jogs.
          • For internal segments: shifts the two segment endpoints along the orthogonal axis only (x for vertical, y for horizontal), preserving orthogonality.
        • Cleans consecutive duplicate points after all edits to avoid degenerate zero-length segments.
      • Returns just the polyline data needed for scoring.
    • scoreOffsets(offsets):
      • Uses the simulated map to sum crossings among all pairwise corrected paths.
      • Prunes if the partial sum exceeds bestScore.
  • Application of chosen configuration

    • After finding the best sign combination (or falling back), the same shift logic is run “for real” and the cleaned polylines are saved to correctedTraceMap.
    • This preserves all prior behaviors:
      • Jogging on terminal segments using applyJogToTerminalSegment.
      • Strict orthogonality enforcement (only x/y displacement).
      • Duplicate-point cleanup.
  • Fallback logic and performance guardrails

    • N>6: Skip brute force and use the original deterministic alternating pattern.
    • Also guard with a short time limit (30 ms) to avoid long scans on edge cases.
    • Both ensure the solver stays responsive and compatible.
  • Visualization unchanged

    • visualize() still:
      • Draws overlapped segments in red using the original geometry.
      • Draws corrected traces in blue dashed using correctedTraceMap.
    • Ensures existing debugging UI remains valid.
  • New test: tests/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver_minCrossings.test.ts

    • Builds 3 nets that share an overlapping vertical segment and diverge horizontally.
    • Runs TraceOverlapIssueSolver and asserts:
      • Resulting polylines remain orthogonal segment-by-segment.
      • Crossings among corrected traces are computed (non-negative sanity check; the test focuses on geometry stability and solver execution path).
    • Includes small, local orthogonal intersection helpers to evaluate crossings in the test.
  • Minor utilities/consistency

    • Kept SHIFT_DISTANCE as the jog size in both simulation and the final application to produce consistent jog geometry.
    • Duplicate point removal kept identical to prior behavior via samePoint helper.

What didn’t change

  • Overlap detection (findNextOverlapIssue) in TraceOverlapShiftSolver was not modified.
  • Jog logic implementation (applyJogToTerminalSegment) remains unchanged; only reused where appropriate.
  • External solver interfaces, inputs, and visualization contracts remained intact.

Why this is safe and compatible

  • Orthogonality preserved: Only axis-aligned displacements; no arbitrary rotations.
  • Minimal and self-contained: New logic is scoped inside _step() and uses only local helpers and existing utilities.
  • Deterministic fallback: If brute-force is skipped or interrupted, behavior exactly matches the original alternating pattern.
  • Performance: Brute force capped at N≤6 and short time limit; for larger N we revert to the original scheme.

If you want code pointers, here are the key areas to review:

  • The new helpers and candidate search/scoring inside _step().

  • The two application passes: one for simulation (applyOffsetsToMap) and one for final application to correctedTraceMap.

  • The unchanged visualize() confirming red-original vs blue-corrected overlays.

  • The new test file under tests/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver_minCrossings.test.ts.

  • Implemented crossing-minimizing search with pruning and fallback; integrated with jog and cleanup.

  • Added orthogonal intersection/crossing helpers inline.

  • Preserved visualization and external behavior; added a multi-trace overlap test.

@vercel
Copy link

vercel bot commented Oct 28, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
schematic-trace-solver Ready Ready Preview Comment Oct 28, 2025 10:22am

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