@tscircuit/schematic-trace-solver 0.0.106 → 0.0.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +470 -213
  3. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +58 -27
  4. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateEndpointCollisionDetours.ts +1 -10
  5. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateInternalSegmentCollisionDetours.ts +94 -0
  6. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/pathOps.ts +10 -0
  7. package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect.ts +5 -1
  8. package/lib/solvers/TraceCleanupSolver/sub-solver/UntangleTraceSubsolver.ts +178 -9
  9. package/lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts +59 -0
  10. package/lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts +64 -1
  11. package/package.json +1 -1
  12. package/tests/bug-reports/bug-report-20260707T140410Z/__snapshots__/bug-report-20260707T140410Z.snap.svg +3 -3
  13. package/tests/bug-reports/bug-report-20260708T095725Z/__snapshots__/bug-report-20260708T095725Z.snap.svg +5 -5
  14. package/tests/bug-reports/bug-report-20260708T095725Z/bug-report-20260708T095725Z.test.ts +15 -0
  15. package/tests/bug-reports/bug-report-20260721T221026Z/__snapshots__/bug-report-20260721T221026Z.snap.svg +1 -1
  16. package/tests/repros/__snapshots__/repro-tps61222-trace-intersection.snap.svg +64 -0
  17. package/tests/repros/__snapshots__/repro47-endpoint-obstacle-detour.snap.svg +1 -1
  18. package/tests/repros/assets/repro-tps61222-trace-intersection.input.json +200 -0
  19. package/tests/repros/repro-tps61222-trace-intersection.test.ts +41 -0
  20. package/tests/repros/repro47-endpoint-obstacle-detour.test.ts +6 -0
  21. package/tests/solvers/SchematicTraceSingleLineSolver2/generate-internal-segment-collision-detours.test.ts +49 -0
@@ -0,0 +1,64 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="1.65,0.09999999999999998 1.65,-0.10000000000000003" data-type="line" data-label="" points="358.0428134556575,324.74300550458713 358.0428134556575,334.5289382262997" fill="none" stroke="hsl(100, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,0.09999999999999998 4.6279125,1.2973754500000003" data-type="line" data-label="" points="358.0428134556575,324.74300550458713 503.7510703363914,266.15582752293574" fill="none" stroke="hsl(100, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,0.09999999999999998 6,0.38" data-type="line" data-label="" points="358.0428134556575,324.74300550458713 570.8868501529053,311.0426996941896" fill="none" stroke="hsl(100, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,-0.10000000000000003 4.6279125,1.2973754500000003" data-type="line" data-label="" points="358.0428134556575,334.5289382262997 503.7510703363914,266.15582752293574" fill="none" stroke="hsl(100, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,-0.10000000000000003 6,0.38" data-type="line" data-label="" points="358.0428134556575,334.5289382262997 570.8868501529053,311.0426996941896" fill="none" stroke="hsl(100, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="4.6279125,1.2973754500000003 6,0.38" data-type="line" data-label="" points="503.7510703363914,266.15582752293574 570.8868501529053,311.0426996941896" fill="none" stroke="hsl(100, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.65,-0.1 -1.65,0.1" data-type="line" data-label="" points="196.5749235474006,334.5289382262997 196.5749235474006,324.74300550458713" fill="none" stroke="hsl(261, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.65,-0.1 -4.4,0.38" data-type="line" data-label="" points="196.5749235474006,334.5289382262997 62.0183486238532,311.0426996941896" fill="none" stroke="hsl(261, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-1.65,0.1 -4.4,0.38" data-type="line" data-label="" points="196.5749235474006,324.74300550458713 62.0183486238532,311.0426996941896" fill="none" stroke="hsl(261, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,-0.30000000000000004 -4.4,-0.38" data-type="line" data-label="" points="358.0428134556575,344.31487094801224 62.0183486238532,348.22924403669725" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,-0.30000000000000004 6,-0.38" data-type="line" data-label="" points="358.0428134556575,344.31487094801224 570.8868501529053,348.22924403669725" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="-4.4,-0.38 6,-0.38" data-type="line" data-label="" points="62.0183486238532,348.22924403669725 570.8868501529053,348.22924403669725" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="1.65,0.30000000000000004 3.5720874999999994,1.3026245499999998" data-type="line" data-label="" points="358.0428134556575,314.9570727828746 452.0899082568807,265.8989908256881" fill="none" stroke="hsl(56, 100%, 50%, 0.8)" stroke-width="1px" stroke-dasharray="4 2"/></g><g><polyline data-points="4.6279125,1.2973754500000003 6,1.2973754500000003 6,0.38" data-type="line" data-label="" points="503.7510703363914,266.15582752293574 570.8868501529053,266.15582752293574 570.8868501529053,311.0426996941896" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.65,0.09999999999999998 4.8279125,0.09999999999999998 4.8279125,1.2973754500000003 4.6279125,1.2973754500000003" data-type="line" data-label="" points="358.0428134556575,324.74300550458713 513.537003058104,324.74300550458713 513.537003058104,266.15582752293574 503.7510703363914,266.15582752293574" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.65,-0.10000000000000003 1.8499999999999999,-0.10000000000000003 1.8499999999999999,0.09999999999999998 1.65,0.09999999999999998" data-type="line" data-label="" points="358.0428134556575,334.5289382262997 367.82874617737,334.5289382262997 367.82874617737,324.74300550458713 358.0428134556575,324.74300550458713" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.65,0.09999999999999976 -1.8499999999999999,0.09999999999999976 -1.8499999999999999,0.5800000000000002 -4.4,0.5800000000000002 -4.4,0.38" data-type="line" data-label="" points="196.5749235474006,324.7430055045872 186.78899082568807,324.7430055045872 186.78899082568807,301.25676697247707 62.0183486238532,301.25676697247707 62.0183486238532,311.0426996941896" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="-1.65,-0.1 -1.8499999999999999,-0.1 -1.8499999999999999,0.1 -1.65,0.1" data-type="line" data-label="" points="196.5749235474006,334.5289382262997 186.78899082568807,334.5289382262997 186.78899082568807,324.74300550458713 196.5749235474006,324.74300550458713" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.6500000000000004,-0.29999999999999993 1.8500000000000005,-0.29999999999999993 1.8500000000000005,-0.9199999999999999 -4.4,-0.9199999999999999 -4.4,-0.38" data-type="line" data-label="" points="358.0428134556575,344.31487094801224 367.82874617737,344.31487094801224 367.82874617737,374.6512623853211 62.0183486238532,374.6512623853211 62.0183486238532,348.22924403669725" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="6,-0.38 6,-0.5800000000000001 1.8500000000000005,-0.5800000000000001 1.8500000000000005,-0.30000000000000004 1.65,-0.30000000000000004" data-type="line" data-label="" points="570.8868501529053,348.22924403669725 570.8868501529053,358.0151767584098 367.82874617737,358.0151767584098 367.82874617737,344.31487094801224 358.0428134556575,344.31487094801224" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.65,0.30000000000000004 2.6110437499999994,0.30000000000000004 2.6110437499999994,1.3026245499999998 3.5720874999999994,1.3026245499999998" data-type="line" data-label="" points="358.0428134556575,314.9570727828746 405.06636085626906,314.9570727828746 405.06636085626906,265.8989908256881 452.0899082568807,265.8989908256881" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="196.5749235474006" y="305.1711400611621" width="161.4678899082569" height="48.92966360856269" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="4.1" data-y="1.3" x="452.08990825688073" y="244.79827889908256" width="51.661162079510746" height="42.458260550458704" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-4.327500000000001" data-y="0" x="39.99999999999996" y="311.0426996941896" width="51.131498470948" height="37.18654434250766" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="6.0725" data-y="0" x="548.868501529052" y="311.0426996941896" width="51.131498470948145" height="37.18654434250766" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="TPS61222DCKT" data-x="-0.53" data-y="-0.63" x="216.14678899082566" y="356.0579902140672" width="70.45871559633028" height="8.807339449541303" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="U2" data-x="-1.13" data-y="0.615" x="213.21100917431193" y="293.42802079510705" width="17.614678899082577" height="12.232415902140644" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="netId: VIN_3V3
2
+ globalConnNetId: connectivity_net0" data-x="6" data-y="1.5073754500000003" x="547.4006116207952" y="245.60536880733946" width="46.97247706422024" height="20.550458715596307" fill="#ef444466" stroke="#ef4444" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="netId: VIN_5V
3
+ globalConnNetId: connectivity_net1" data-x="-4.4" data-y="0.7900000000000001" x="41.46788990825688" y="280.7063082568807" width="41.10091743119264" height="20.550458715596335" fill="#ef444466" stroke="#ef4444" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="netId: GND
4
+ globalConnNetId: connectivity_net2" data-x="-4.4" data-y="-1.13" x="50.27522935779815" y="374.65126238532105" width="23.486238532110093" height="20.550458715596335" fill="#00000066" stroke="#000000" stroke-width="0.0204375"/></g><g><rect data-type="rect" data-label="netId: BOOST_SW
5
+ globalConnNetId: connectivity_net3" data-x="3.1510437499999995" data-y="0.30000000000000004" x="405.06636085626906" y="310.0641064220183" width="52.8440366972477" height="9.785932721712527" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.0204375"/></g><g><circle data-type="point" data-label="U2.1
6
+ x+" data-x="1.65" data-y="0.09999999999999998" cx="358.0428134556575" cy="324.74300550458713" r="3" fill="hsl(200, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U2.2
7
+ x-" data-x="-1.65" data-y="-0.1" cx="196.5749235474006" cy="334.5289382262997" r="3" fill="hsl(201, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U2.3
8
+ x+" data-x="1.65" data-y="-0.30000000000000004" cx="358.0428134556575" cy="344.31487094801224" r="3" fill="hsl(202, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U2.4
9
+ x-" data-x="-1.65" data-y="0.1" cx="196.5749235474006" cy="324.74300550458713" r="3" fill="hsl(203, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U2.5
10
+ x+" data-x="1.65" data-y="0.30000000000000004" cx="358.0428134556575" cy="314.9570727828746" r="3" fill="hsl(204, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U2.6
11
+ x+" data-x="1.65" data-y="-0.10000000000000003" cx="358.0428134556575" cy="334.5289382262997" r="3" fill="hsl(205, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="L4.1
12
+ x-" data-x="3.5720874999999994" data-y="1.3026245499999998" cx="452.0899082568807" cy="265.8989908256881" r="3" fill="hsl(43, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="L4.2
13
+ x+" data-x="4.6279125" data-y="1.2973754500000003" cx="503.7510703363914" cy="266.15582752293574" r="3" fill="hsl(44, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="C25.1
14
+ y+" data-x="-4.4" data-y="0.38" cx="62.0183486238532" cy="311.0426996941896" r="3" fill="hsl(265, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="C25.2
15
+ y-" data-x="-4.4" data-y="-0.38" cx="62.0183486238532" cy="348.22924403669725" r="3" fill="hsl(266, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="C26.1
16
+ y+" data-x="6" data-y="0.38" cx="570.8868501529053" cy="311.0426996941896" r="3" fill="hsl(146, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="C26.2
17
+ y-" data-x="6" data-y="-0.38" cx="570.8868501529053" cy="348.22924403669725" r="3" fill="hsl(147, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
18
+ orientation: y+" data-x="6" data-y="1.2973754500000003" cx="570.8868501529053" cy="266.15582752293574" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
19
+ orientation: y+" data-x="-4.4" data-y="0.5800000000000002" cx="62.0183486238532" cy="301.25676697247707" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
20
+ orientation: y-" data-x="-4.4" data-y="-0.9199999999999999" cx="62.0183486238532" cy="374.6512623853211" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
21
+ orientation: x+" data-x="2.6110437499999994" data-y="0.30000000000000004" cx="405.06636085626906" cy="314.9570727828746" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5"/><line id="crosshair-v" x1="0" x2="640" stroke="#666" stroke-width="0.5"/><text id="coordinates" font-family="monospace" font-size="12" fill="#666"></text></g><script><![CDATA[
22
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
23
+ const svg = e.currentTarget;
24
+ const rect = svg.getBoundingClientRect();
25
+ const x = e.clientX - rect.left;
26
+ const y = e.clientY - rect.top;
27
+ const crosshair = svg.getElementById('crosshair');
28
+ const h = svg.getElementById('crosshair-h');
29
+ const v = svg.getElementById('crosshair-v');
30
+ const coords = svg.getElementById('coordinates');
31
+
32
+ crosshair.style.display = 'block';
33
+ h.setAttribute('x1', '0');
34
+ h.setAttribute('x2', '640');
35
+ h.setAttribute('y1', y);
36
+ h.setAttribute('y2', y);
37
+ v.setAttribute('x1', x);
38
+ v.setAttribute('x2', x);
39
+ v.setAttribute('y1', '0');
40
+ v.setAttribute('y2', '640');
41
+
42
+ // Calculate real coordinates using inverse transformation
43
+ const matrix = {"a":48.92966360856269,"c":0,"e":277.30886850152905,"b":0,"d":-48.92966360856269,"f":329.6359718654434};
44
+ // Manually invert and apply the affine transform
45
+ // Since we only use translate and scale, we can directly compute:
46
+ // x' = (x - tx) / sx
47
+ // y' = (y - ty) / sy
48
+ const sx = matrix.a;
49
+ const sy = matrix.d;
50
+ const tx = matrix.e;
51
+ const ty = matrix.f;
52
+ const realPoint = {
53
+ x: (x - tx) / sx,
54
+ y: (y - ty) / sy // Flip y back since we used negative scale
55
+ }
56
+
57
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
58
+ coords.setAttribute('x', (x + 5).toString());
59
+ coords.setAttribute('y', (y - 5).toString());
60
+ });
61
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
62
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
63
+ });
64
+ ]]></script></svg>
@@ -1,4 +1,4 @@
1
- <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="0.6499999999999999,0.825 -0.6499999999999999,-0.825" data-type="line" data-label="" points="419.0769230769231,177.84615384615384 195.0769230769231,462.1538461538462" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.25,0.825 -1.25,-0.825" data-type="line" data-label="" points="522.4615384615386,177.84615384615384 91.69230769230768,462.1538461538462" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.49999999999999994,-0.725 -1.25,0.825" data-type="line" data-label="" points="393.2307692307692,444.9230769230769 91.69230769230768,177.84615384615384" fill="none" stroke="hsl(168, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.4,-0.725 -0.6499999999999999,0.825" data-type="line" data-label="" points="548.3076923076924,444.9230769230769 195.0769230769231,177.84615384615384" fill="none" stroke="hsl(168, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.6499999999999999,0.825 0,0.825 0,-0.825 -0.6499999999999999,-0.825" data-type="line" data-label="" points="419.0769230769231,177.84615384615384 307.0769230769231,177.84615384615384 307.0769230769231,462.1538461538462 195.0769230769231,462.1538461538462" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.25,0.825 1.4500000000000002,0.825 1.4500000000000002,0 -1.3499999999999999,0 -1.3499999999999999,-0.825 -1.25,-0.825" data-type="line" data-label="" points="522.4615384615386,177.84615384615384 556.923076923077,177.84615384615384 556.923076923077,320 74.46153846153848,320 74.46153846153848,462.1538461538462 91.69230769230768,462.1538461538462" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0.5,-0.725 0.2,-0.725 0.2,-1.365 -1.55,-1.365 -1.55,0.825 -1.25,0.825" data-type="line" data-label="" points="393.2307692307693,444.9230769230769 341.53846153846155,444.9230769230769 341.53846153846155,555.2 40,555.2 40,177.84615384615384 91.69230769230768,177.84615384615384" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.4,-0.725 1.5999999999999999,-0.725 1.5999999999999999,1.365 -0.1,1.365 -0.1,0.825 -0.6499999999999999,0.825" data-type="line" data-label="" points="548.3076923076924,444.9230769230769 582.7692307692307,444.9230769230769 582.7692307692307,84.79999999999998 289.84615384615387,84.79999999999998 289.84615384615387,177.84615384615384 195.0769230769231,177.84615384615384" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="-0.95" data-y="0.825" x="91.69230769230768" y="119.26153846153844" width="103.38461538461542" height="117.16923076923081" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="0.95" data-y="0.825" x="419.0769230769231" y="119.26153846153844" width="103.38461538461547" height="117.16923076923081" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-0.95" data-y="-0.825" x="91.69230769230768" y="403.5692307692308" width="103.38461538461542" height="117.16923076923081" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="0.95" data-y="-0.825" x="393.2307692307693" y="414.2732025415385" width="155.07692307692315" height="95.76128722461533" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="netId: .J1 &gt; .pin1 to .R1 &gt; .pin1
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="0.6499999999999999,0.825 -0.6499999999999999,-0.825" data-type="line" data-label="" points="419.0769230769231,177.84615384615384 195.0769230769231,462.1538461538462" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.25,0.825 -1.25,-0.825" data-type="line" data-label="" points="522.4615384615386,177.84615384615384 91.69230769230768,462.1538461538462" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.49999999999999994,-0.725 -1.25,0.825" data-type="line" data-label="" points="393.2307692307692,444.9230769230769 91.69230769230768,177.84615384615384" fill="none" stroke="hsl(168, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.4,-0.725 -0.6499999999999999,0.825" data-type="line" data-label="" points="548.3076923076924,444.9230769230769 195.0769230769231,177.84615384615384" fill="none" stroke="hsl(168, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.6499999999999999,0.825 0,0.825 0,-0.825 -0.6499999999999999,-0.825" data-type="line" data-label="" points="419.0769230769231,177.84615384615384 307.0769230769231,177.84615384615384 307.0769230769231,462.1538461538462 195.0769230769231,462.1538461538462" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.25,0.825 1.4500000000000002,0.825 1.4500000000000002,-0.18893936762499997 0.050000000000000155,-0.18893936762499997 0.050000000000000155,-1.2028787352499999 -1.3499999999999999,-1.2028787352499999 -1.3499999999999999,-0.825 -1.25,-0.825" data-type="line" data-label="" points="522.4615384615386,177.84615384615384 556.923076923077,177.84615384615384 556.923076923077,352.55570642153845 315.69230769230774,352.55570642153845 315.69230769230774,527.2652589969231 74.46153846153848,527.2652589969231 74.46153846153848,462.1538461538462 91.69230769230768,462.1538461538462" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="0.5,-0.725 0.2,-0.725 0.2,-1.365 -1.55,-1.365 -1.55,0.825 -1.25,0.825" data-type="line" data-label="" points="393.2307692307693,444.9230769230769 341.53846153846155,444.9230769230769 341.53846153846155,555.2 40,555.2 40,177.84615384615384 91.69230769230768,177.84615384615384" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.4,-0.725 1.5999999999999999,-0.725 1.5999999999999999,1.365 -0.1,1.365 -0.1,0.825 -0.6499999999999999,0.825" data-type="line" data-label="" points="548.3076923076924,444.9230769230769 582.7692307692307,444.9230769230769 582.7692307692307,84.79999999999998 289.84615384615387,84.79999999999998 289.84615384615387,177.84615384615384 195.0769230769231,177.84615384615384" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="-0.95" data-y="0.825" x="91.69230769230768" y="119.26153846153844" width="103.38461538461542" height="117.16923076923081" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="0.95" data-y="0.825" x="419.0769230769231" y="119.26153846153844" width="103.38461538461547" height="117.16923076923081" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-0.95" data-y="-0.825" x="91.69230769230768" y="403.5692307692308" width="103.38461538461542" height="117.16923076923081" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="0.95" data-y="-0.825" x="393.2307692307693" y="414.2732025415385" width="155.07692307692315" height="95.76128722461533" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="netId: .J1 &gt; .pin1 to .R1 &gt; .pin1
2
2
  globalConnNetId: connectivity_net2" data-x="0.35" data-y="-0.5" x="350.1538461538462" y="367.3846153846155" width="34.46153846153845" height="77.53846153846149" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="netId: .J1 &gt; .pin3 to .R1 &gt; .pin2
3
3
  globalConnNetId: connectivity_net3" data-x="1.5999999999999999" data-y="-0.95" x="565.5384615384614" y="444.92307692307696" width="34.46153846153845" height="77.53846153846155" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="netId: .R2 &gt; .pin1 to .R3 &gt; .pin2
4
4
  globalConnNetId: connectivity_net0" data-x="0.32499999999999996" data-y="1.05" x="345.84615384615387" y="100.30769230769229" width="34.46153846153845" height="77.53846153846155" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.005803571428571428"/></g><g><rect data-type="rect" data-label="netId: .R2 &gt; .pin2 to .R3 &gt; .pin1
@@ -0,0 +1,200 @@
1
+ {
2
+ "chips": [
3
+ {
4
+ "chipId": "schematic_component_0",
5
+ "center": {
6
+ "x": 0,
7
+ "y": 0
8
+ },
9
+ "width": 2.5,
10
+ "height": 1,
11
+ "pins": [
12
+ {
13
+ "pinId": "U2.1",
14
+ "x": 1.65,
15
+ "y": 0.09999999999999998,
16
+ "_facingDirection": "x+"
17
+ },
18
+ {
19
+ "pinId": "U2.2",
20
+ "x": -1.65,
21
+ "y": -0.1,
22
+ "_facingDirection": "x-"
23
+ },
24
+ {
25
+ "pinId": "U2.3",
26
+ "x": 1.65,
27
+ "y": -0.30000000000000004,
28
+ "_facingDirection": "x+"
29
+ },
30
+ {
31
+ "pinId": "U2.4",
32
+ "x": -1.65,
33
+ "y": 0.1,
34
+ "_facingDirection": "x-"
35
+ },
36
+ {
37
+ "pinId": "U2.5",
38
+ "x": 1.65,
39
+ "y": 0.30000000000000004,
40
+ "_facingDirection": "x+"
41
+ },
42
+ {
43
+ "pinId": "U2.6",
44
+ "x": 1.65,
45
+ "y": -0.10000000000000003,
46
+ "_facingDirection": "x+"
47
+ }
48
+ ]
49
+ },
50
+ {
51
+ "chipId": "schematic_component_1",
52
+ "center": {
53
+ "x": 4.1,
54
+ "y": 1.3
55
+ },
56
+ "width": 1.0555194999999995,
57
+ "height": 0.8677407000000001,
58
+ "pins": [
59
+ {
60
+ "pinId": "L4.1",
61
+ "x": 3.5720874999999994,
62
+ "y": 1.3026245499999998,
63
+ "_facingDirection": "x-"
64
+ },
65
+ {
66
+ "pinId": "L4.2",
67
+ "x": 4.6279125,
68
+ "y": 1.2973754500000003,
69
+ "_facingDirection": "x+"
70
+ }
71
+ ]
72
+ },
73
+ {
74
+ "chipId": "schematic_component_2",
75
+ "center": {
76
+ "x": -4.327500000000001,
77
+ "y": 0
78
+ },
79
+ "width": 1.0450000000000004,
80
+ "height": 0.76,
81
+ "pins": [
82
+ {
83
+ "pinId": "C25.1",
84
+ "x": -4.4,
85
+ "y": 0.3,
86
+ "_facingDirection": "y+"
87
+ },
88
+ {
89
+ "pinId": "C25.2",
90
+ "x": -4.4,
91
+ "y": -0.3,
92
+ "_facingDirection": "y-"
93
+ }
94
+ ]
95
+ },
96
+ {
97
+ "chipId": "schematic_component_3",
98
+ "center": {
99
+ "x": 6.0725,
100
+ "y": 0
101
+ },
102
+ "width": 1.0450000000000008,
103
+ "height": 0.76,
104
+ "pins": [
105
+ {
106
+ "pinId": "C26.1",
107
+ "x": 6,
108
+ "y": 0.3,
109
+ "_facingDirection": "y+"
110
+ },
111
+ {
112
+ "pinId": "C26.2",
113
+ "x": 6,
114
+ "y": -0.3,
115
+ "_facingDirection": "y-"
116
+ }
117
+ ]
118
+ }
119
+ ],
120
+ "directConnections": [],
121
+ "netConnections": [
122
+ {
123
+ "netId": "VIN_3V3",
124
+ "pinIds": [
125
+ "U2.1",
126
+ "U2.6",
127
+ "L4.2",
128
+ "C26.1"
129
+ ],
130
+ "netLabelWidth": 0.42,
131
+ "netLabelHeight": 0.96
132
+ },
133
+ {
134
+ "netId": "VIN_5V",
135
+ "pinIds": [
136
+ "U2.2",
137
+ "U2.4",
138
+ "C25.1"
139
+ ],
140
+ "netLabelWidth": 0.42,
141
+ "netLabelHeight": 0.84
142
+ },
143
+ {
144
+ "netId": "GND",
145
+ "pinIds": [
146
+ "U2.3",
147
+ "C25.2",
148
+ "C26.2"
149
+ ],
150
+ "netLabelWidth": 0.42,
151
+ "netLabelHeight": 0.48
152
+ },
153
+ {
154
+ "netId": "BOOST_SW",
155
+ "pinIds": [
156
+ "U2.5",
157
+ "L4.1"
158
+ ],
159
+ "netLabelWidth": 1.08
160
+ }
161
+ ],
162
+ "textBoxes": [
163
+ {
164
+ "chipId": "schematic_component_0",
165
+ "center": {
166
+ "x": -0.53,
167
+ "y": -0.63
168
+ },
169
+ "width": 1.44,
170
+ "height": 0.17999999999999994,
171
+ "text": "TPS61222DCKT"
172
+ },
173
+ {
174
+ "chipId": "schematic_component_0",
175
+ "center": {
176
+ "x": -1.13,
177
+ "y": 0.615
178
+ },
179
+ "width": 0.3600000000000001,
180
+ "height": 0.25,
181
+ "text": "U2"
182
+ }
183
+ ],
184
+ "availableNetLabelOrientations": {
185
+ "VIN_3V3": [
186
+ "y+"
187
+ ],
188
+ "VIN_5V": [
189
+ "y+"
190
+ ],
191
+ "GND": [
192
+ "y-"
193
+ ],
194
+ "BOOST_SW": [
195
+ "x-",
196
+ "x+"
197
+ ]
198
+ },
199
+ "maxMspPairDistance": 20
200
+ }
@@ -0,0 +1,41 @@
1
+ import { expect, test } from "bun:test"
2
+ import { isPathCollidingWithObstacles } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions"
3
+ import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
4
+ import { getTextBoxBounds } from "lib/utils/textBoxBounds"
5
+ import "tests/fixtures/matcher"
6
+ import inputProblem from "./assets/repro-tps61222-trace-intersection.input.json"
7
+
8
+ // Extracted from https://github.com/tscircuit/core/pull/2785 with
9
+ // DEBUG=Group_doInitialSchematicTraceRender.
10
+ test("repro TPS61222 schematic trace intersection", () => {
11
+ const solver = new SchematicTracePipelineSolver(inputProblem as any)
12
+
13
+ const manufacturerPartNumberTextBox = inputProblem.textBoxes.find(
14
+ (textBox) => textBox.text === "TPS61222DCKT",
15
+ )
16
+ expect(manufacturerPartNumberTextBox).toBeDefined()
17
+
18
+ const textBounds = getTextBoxBounds(manufacturerPartNumberTextBox!)
19
+ solver.solveUntilPhase("longDistancePairSolver")
20
+
21
+ const initialGroundTrace =
22
+ solver.schematicTraceLinesSolver!.solvedTracePaths.find(
23
+ (trace) => trace.mspPairId === "U2.3-C25.2",
24
+ )
25
+ expect(initialGroundTrace).toBeDefined()
26
+ expect(
27
+ isPathCollidingWithObstacles(initialGroundTrace!.tracePath, [textBounds]),
28
+ ).toBe(false)
29
+
30
+ solver.solve()
31
+
32
+ const crossingTraceIds = solver
33
+ .netLabelTraceCollisionSolver!.getOutput()
34
+ .traces.filter((trace) =>
35
+ isPathCollidingWithObstacles(trace.tracePath, [textBounds]),
36
+ )
37
+ .map((trace) => trace.mspPairId)
38
+
39
+ expect(crossingTraceIds).toEqual([])
40
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
41
+ })
@@ -44,6 +44,12 @@ test("repro47: endpoint obstacle detours route around nearby components", () =>
44
44
  traceById.get("R2.1-R3.2")!.tracePath,
45
45
  ),
46
46
  ).toBe(0)
47
+ expect(
48
+ countPathIntersections(
49
+ traceById.get("R2.1-R3.2")!.tracePath,
50
+ traceById.get("R2.2-R3.1")!.tracePath,
51
+ ),
52
+ ).toBe(0)
47
53
 
48
54
  expect(solver).toMatchSolverSnapshot(import.meta.path)
49
55
  })
@@ -0,0 +1,49 @@
1
+ import { expect, test } from "bun:test"
2
+ import { isPathCollidingWithObstacles } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/collisions"
3
+ import { generateInternalSegmentCollisionDetours } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/generateInternalSegmentCollisionDetours"
4
+
5
+ test("internal segment detours preserve endpoint legs and clear the obstacle", () => {
6
+ const path = [
7
+ { x: 0, y: 0 },
8
+ { x: 1, y: 0 },
9
+ { x: 9, y: 0 },
10
+ { x: 10, y: 0 },
11
+ ]
12
+ const obstacle = { minX: 4, minY: -0.5, maxX: 6, maxY: 0.5 }
13
+
14
+ const detours = generateInternalSegmentCollisionDetours({
15
+ path,
16
+ collidingSegmentIndex: 1,
17
+ obstacle,
18
+ })
19
+
20
+ expect(detours).toHaveLength(2)
21
+ for (const detour of detours) {
22
+ expect(detour.slice(0, 2)).toEqual(path.slice(0, 2))
23
+ expect(detour.slice(-2)).toEqual(path.slice(-2))
24
+ expect(isPathCollidingWithObstacles(detour, [obstacle])).toBe(false)
25
+ }
26
+ })
27
+
28
+ test("internal segment detours support vertical paths", () => {
29
+ const path = [
30
+ { x: 0, y: 0 },
31
+ { x: 0, y: 1 },
32
+ { x: 0, y: 9 },
33
+ { x: 0, y: 10 },
34
+ ]
35
+ const obstacle = { minX: -0.5, minY: 4, maxX: 0.5, maxY: 6 }
36
+
37
+ const detours = generateInternalSegmentCollisionDetours({
38
+ path,
39
+ collidingSegmentIndex: 1,
40
+ obstacle,
41
+ })
42
+
43
+ expect(detours).toHaveLength(2)
44
+ expect(
45
+ detours.every(
46
+ (detour) => !isPathCollidingWithObstacles(detour, [obstacle]),
47
+ ),
48
+ ).toBe(true)
49
+ })