@tscircuit/schematic-trace-solver 0.0.41 → 0.0.42

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 (46) hide show
  1. package/dist/index.d.ts +118 -7
  2. package/dist/index.js +760 -432
  3. package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +30 -17
  4. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/TraceLabelOverlapAvoidanceSolver.ts +94 -192
  5. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/rerouteCollidingTrace.ts +13 -24
  6. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver.ts +205 -0
  7. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/OverlapAvoidanceStepSolver/OverlapAvoidanceStepSolver.ts +144 -0
  8. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver.ts +117 -0
  9. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/TraceCleanupSolver/TraceCleanupSolver.ts +132 -0
  10. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{balanceLShapes.ts → sub-solvers/TraceCleanupSolver/balanceLShapes.ts} +12 -10
  11. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{hasCollisions.ts → sub-solvers/TraceCleanupSolver/hasCollisions.ts} +1 -1
  12. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{hasCollisionsWithLabels.ts → sub-solvers/TraceCleanupSolver/hasCollisionsWithLabels.ts} +1 -1
  13. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{minimizeTurnsWithFilteredLabels.ts → sub-solvers/TraceCleanupSolver/minimizeTurnsWithFilteredLabels.ts} +6 -6
  14. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{simplifyPath.ts → sub-solvers/TraceCleanupSolver/simplifyPath.ts} +1 -1
  15. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{turnMinimization.ts → sub-solvers/TraceCleanupSolver/turnMinimization.ts} +0 -2
  16. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/tryFourPointDetour.ts +104 -0
  17. package/lib/solvers/TraceLabelOverlapAvoidanceSolver/trySnipAndReconnect.ts +24 -154
  18. package/package.json +1 -1
  19. package/tests/assets/1.input.json +379 -0
  20. package/tests/assets/2.input.json +330 -0
  21. package/tests/assets/3.input.json +388 -0
  22. package/tests/assets/MergedNetLabelObstacles.test.input.json +154 -0
  23. package/tests/assets/OverlapAvoidanceStepSolver.test.input.json +682 -0
  24. package/tests/assets/SingleOverlapSolver.test.input.json +170 -0
  25. package/tests/assets/TraceCleanupSolver.test.input.json +216 -0
  26. package/tests/assets/TraceLabelOverlapAvoidanceSolver.test.input.json +424 -0
  27. package/tests/examples/__snapshots__/example25.snap.svg +3 -3
  28. package/tests/examples/__snapshots__/example26.snap.svg +3 -3
  29. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/TraceLabelOverlapAvoidanceSolver.test.ts +18 -0
  30. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/__snapshots__/TraceLabelOverlapAvoidanceSolver.snap.svg +243 -0
  31. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/__snapshots__/renderComparisonView01.snap.svg +223 -0
  32. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/__snapshots__/renderComparisonView02.snap.svg +205 -0
  33. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/__snapshots__/renderComparisonView03.snap.svg +184 -0
  34. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/renderComparisonView01.test.ts +29 -0
  35. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/renderComparisonView02.test.ts +27 -0
  36. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/renderComparisonView/renderComparisonView03.test.ts +39 -0
  37. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/MergedNetLabelObstacles.test.ts +14 -0
  38. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/OverlapAvoidanceStepSolver.test.ts +20 -0
  39. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/SingleOverlapSolver.test.ts +10 -0
  40. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/TraceCleanupSolver.test.ts +19 -0
  41. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/MergedNetLabelObstacles.snap.svg +140 -0
  42. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/OverlapAvoidanceStepSolver.snap.svg +216 -0
  43. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/SingleOverlapSolver.snap.svg +125 -0
  44. package/tests/solvers/TraceLabelOverlapAvoidanceSolver/sub-solver/__snapshots__/TraceCleanupSolver.snap.svg +119 -0
  45. /package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{countTurns.ts → sub-solvers/TraceCleanupSolver/countTurns.ts} +0 -0
  46. /package/lib/solvers/TraceLabelOverlapAvoidanceSolver/{tryConnectPoints.ts → sub-solvers/TraceCleanupSolver/tryConnectPoints.ts} +0 -0
@@ -0,0 +1,205 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="100%" height="100%" fill="white" />
3
+ <g>
4
+ <circle data-type="point" data-label="U1.1
5
+ x+" data-x="1.2000000000000002" data-y="-0.30000000000000004" cx="159.4666666666667" cy="286.0577777777778" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
6
+ </g>
7
+ <g>
8
+ <circle data-type="point" data-label="U1.2
9
+ x-" data-x="-1.2000000000000002" data-y="-0.30000000000000004" cx="40.00000000000001" cy="286.0577777777778" r="3" fill="hsl(320, 100%, 50%, 0.8)" />
10
+ </g>
11
+ <g>
12
+ <circle data-type="point" data-label="U1.3
13
+ x+" data-x="1.2000000000000002" data-y="0.09999999999999998" cx="159.4666666666667" cy="266.1466666666667" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
14
+ </g>
15
+ <g>
16
+ <circle data-type="point" data-label="U1.4
17
+ x-" data-x="-1.2000000000000002" data-y="0.30000000000000004" cx="40.00000000000001" cy="256.1911111111111" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
18
+ </g>
19
+ <g>
20
+ <circle data-type="point" data-label="U1.5
21
+ x-" data-x="-1.2000000000000002" data-y="0.10000000000000003" cx="40.00000000000001" cy="266.1466666666667" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
22
+ </g>
23
+ <g>
24
+ <circle data-type="point" data-label="U1.6
25
+ x-" data-x="-1.2000000000000002" data-y="-0.09999999999999998" cx="40.00000000000001" cy="276.1022222222222" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
26
+ </g>
27
+ <g>
28
+ <circle data-type="point" data-label="U1.7
29
+ x+" data-x="1.2000000000000002" data-y="-0.10000000000000003" cx="159.4666666666667" cy="276.1022222222222" r="3" fill="hsl(325, 100%, 50%, 0.8)" />
30
+ </g>
31
+ <g>
32
+ <circle data-type="point" data-label="U1.8
33
+ x+" data-x="1.2000000000000002" data-y="0.30000000000000004" cx="159.4666666666667" cy="256.1911111111111" r="3" fill="hsl(326, 100%, 50%, 0.8)" />
34
+ </g>
35
+ <g>
36
+ <circle data-type="point" data-label="J1.1
37
+ x-" data-x="1.6" data-y="-1.895" cx="179.3777777777778" cy="365.4533333333334" r="3" fill="hsl(218, 100%, 50%, 0.8)" />
38
+ </g>
39
+ <g>
40
+ <circle data-type="point" data-label="J1.2
41
+ x-" data-x="1.6" data-y="-2.095" cx="179.3777777777778" cy="375.4088888888889" r="3" fill="hsl(219, 100%, 50%, 0.8)" />
42
+ </g>
43
+ <g>
44
+ <circle data-type="point" data-label="J1.3
45
+ x-" data-x="1.6" data-y="-2.295" cx="179.3777777777778" cy="385.3644444444445" r="3" fill="hsl(220, 100%, 50%, 0.8)" />
46
+ </g>
47
+ <g>
48
+ <circle data-type="point" data-label="U1.1
49
+ x+" data-x="7.450000000000001" data-y="-0.55" cx="470.57777777777784" cy="298.50222222222226" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
50
+ </g>
51
+ <g>
52
+ <circle data-type="point" data-label="U1.2
53
+ x-" data-x="5.050000000000001" data-y="-0.55" cx="351.1111111111112" cy="298.50222222222226" r="3" fill="hsl(320, 100%, 50%, 0.8)" />
54
+ </g>
55
+ <g>
56
+ <circle data-type="point" data-label="U1.3
57
+ x+" data-x="7.450000000000001" data-y="-0.15000000000000002" cx="470.57777777777784" cy="278.5911111111111" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
58
+ </g>
59
+ <g>
60
+ <circle data-type="point" data-label="U1.4
61
+ x-" data-x="5.050000000000001" data-y="0.050000000000000044" cx="351.1111111111112" cy="268.6355555555556" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
62
+ </g>
63
+ <g>
64
+ <circle data-type="point" data-label="U1.5
65
+ x-" data-x="5.050000000000001" data-y="-0.14999999999999997" cx="351.1111111111112" cy="278.5911111111111" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
66
+ </g>
67
+ <g>
68
+ <circle data-type="point" data-label="U1.6
69
+ x-" data-x="5.050000000000001" data-y="-0.35" cx="351.1111111111112" cy="288.5466666666667" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
70
+ </g>
71
+ <g>
72
+ <circle data-type="point" data-label="U1.7
73
+ x+" data-x="7.450000000000001" data-y="-0.35000000000000003" cx="470.57777777777784" cy="288.5466666666667" r="3" fill="hsl(325, 100%, 50%, 0.8)" />
74
+ </g>
75
+ <g>
76
+ <circle data-type="point" data-label="U1.8
77
+ x+" data-x="7.450000000000001" data-y="0.050000000000000044" cx="470.57777777777784" cy="268.6355555555556" r="3" fill="hsl(326, 100%, 50%, 0.8)" />
78
+ </g>
79
+ <g>
80
+ <circle data-type="point" data-label="J1.1
81
+ x-" data-x="7.850000000000001" data-y="-2.145" cx="490.488888888889" cy="377.89777777777783" r="3" fill="hsl(218, 100%, 50%, 0.8)" />
82
+ </g>
83
+ <g>
84
+ <circle data-type="point" data-label="J1.2
85
+ x-" data-x="7.850000000000001" data-y="-2.345" cx="490.488888888889" cy="387.85333333333335" r="3" fill="hsl(219, 100%, 50%, 0.8)" />
86
+ </g>
87
+ <g>
88
+ <circle data-type="point" data-label="J1.3
89
+ x-" data-x="7.850000000000001" data-y="-2.545" cx="490.488888888889" cy="397.8088888888889" r="3" fill="hsl(220, 100%, 50%, 0.8)" />
90
+ </g>
91
+ <g>
92
+ <polyline data-points="1.2000000000000002,-0.30000000000000004 1.6,-2.295" data-type="line" data-label="" points="159.4666666666667,286.0577777777778 179.3777777777778,385.3644444444445" fill="none" stroke="hsl(157, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
93
+ </g>
94
+ <g>
95
+ <polyline data-points="1.2000000000000002,0.30000000000000004 1.6,-1.895" data-type="line" data-label="" points="159.4666666666667,256.1911111111111 179.3777777777778,365.4533333333334" fill="none" stroke="hsl(190, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
96
+ </g>
97
+ <g>
98
+ <polyline data-points="1.2000000000000002,-0.30000000000000004 1.4000000000000001,-0.30000000000000004 1.4000000000000001,-1.2974999999999999 1.4000000000000001,-2.295 1.6,-2.295" data-type="line" data-label="" points="159.4666666666667,286.0577777777778 169.42222222222225,286.0577777777778 169.42222222222225,335.7111111111111 169.42222222222225,385.3644444444445 179.3777777777778,385.3644444444445" fill="none" stroke="blue" stroke-width="1" />
99
+ </g>
100
+ <g>
101
+ <polyline data-points="1.149,-1.995 1.5990000000000002,-1.995 1.5990000000000002,-1.795 1.149,-1.795 1.149,-1.995" data-type="line" data-label="" points="156.92800000000003,370.43111111111114 179.32800000000003,370.43111111111114 179.32800000000003,360.47555555555556 156.92800000000003,360.47555555555556 156.92800000000003,370.43111111111114" fill="none" stroke="hsl(296, 100%, 50%, 1)" stroke-width="1" stroke-dasharray="4 4" />
102
+ </g>
103
+ <g>
104
+ <polyline data-points="1.374,-1.895 1.374,-1.995" data-type="line" data-label="" points="168.12800000000004,365.4533333333334 168.12800000000004,370.43111111111114" fill="none" stroke="hsl(296, 100%, 50%, 1)" stroke-width="1" stroke-dasharray="2 2" />
105
+ </g>
106
+ <g>
107
+ <polyline data-points="1.149,-2.1950000000000003 1.5990000000000002,-2.1950000000000003 1.5990000000000002,-1.995 1.149,-1.995 1.149,-2.1950000000000003" data-type="line" data-label="" points="156.92800000000003,380.3866666666667 179.32800000000003,380.3866666666667 179.32800000000003,370.43111111111114 156.92800000000003,370.43111111111114 156.92800000000003,380.3866666666667" fill="none" stroke="hsl(296, 100%, 50%, 1)" stroke-width="1" stroke-dasharray="4 4" />
108
+ </g>
109
+ <g>
110
+ <polyline data-points="1.374,-2.095 1.374,-1.995" data-type="line" data-label="" points="168.12800000000004,375.4088888888889 168.12800000000004,370.43111111111114" fill="none" stroke="hsl(296, 100%, 50%, 1)" stroke-width="1" stroke-dasharray="2 2" />
111
+ </g>
112
+ <g>
113
+ <polyline data-points="7.450000000000001,-0.55 7.850000000000001,-2.545" data-type="line" data-label="" points="470.57777777777784,298.50222222222226 490.488888888889,397.8088888888889" fill="none" stroke="hsl(157, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
114
+ </g>
115
+ <g>
116
+ <polyline data-points="7.450000000000001,0.050000000000000044 7.850000000000001,-2.145" data-type="line" data-label="" points="470.57777777777784,268.6355555555556 490.488888888889,377.89777777777783" fill="none" stroke="hsl(190, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
117
+ </g>
118
+ <g>
119
+ <polyline data-points="7.450000000000001,-0.55 7.650000000000001,-0.55 7.650000000000001,-1.5474999999999999 7.650000000000001,-2.545 7.850000000000001,-2.545" data-type="line" data-label="" points="470.57777777777784,298.50222222222226 480.5333333333334,298.50222222222226 480.5333333333334,348.15555555555557 480.5333333333334,397.8088888888889 490.488888888889,397.8088888888889" fill="none" stroke="red" stroke-width="1" stroke-dasharray="4 4" />
120
+ </g>
121
+ <g>
122
+ <polyline data-points="7.450000000000001,-0.55 7.650000000000001,-0.55 7.650000000000001,-1.9449999999999998 7.299000000000001,-1.9449999999999998 7.299000000000001,-2.5450000000000004 7.850000000000001,-2.545" data-type="line" data-label="" points="470.57777777777784,298.50222222222226 480.5333333333334,298.50222222222226 480.5333333333334,367.94222222222226 463.06133333333344,367.94222222222226 463.06133333333344,397.80888888888893 490.488888888889,397.8088888888889" fill="none" stroke="green" stroke-width="1" />
123
+ </g>
124
+ <g>
125
+ <rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="40.00000000000001" y="246.23555555555558" width="119.4666666666667" height="49.7777777777778" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
126
+ </g>
127
+ <g>
128
+ <rect data-type="rect" data-label="schematic_component_1" data-x="2.7" data-y="-2.095" x="179.3777777777778" y="355.4977777777778" width="109.51111111111112" height="39.82222222222225" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
129
+ </g>
130
+ <g>
131
+ <rect data-type="rect" data-label="connectivity_net0" data-x="1.4000000000000001" data-y="-2.52" x="164.44444444444446" y="385.3644444444445" width="9.955555555555577" height="22.400000000000034" fill="none" stroke="hsl(40, 100%, 50%, 1)" stroke-width="0.020089285714285712" />
132
+ </g>
133
+ <g>
134
+ <rect data-type="rect" data-label="connectivity_net1" data-x="1.4260000000000002" data-y="0.30000000000000004" x="159.51644444444446" y="251.21333333333337" width="22.400000000000034" height="9.95555555555552" fill="none" stroke="hsl(40, 100%, 50%, 1)" stroke-width="0.020089285714285712" />
135
+ </g>
136
+ <g>
137
+ <rect data-type="rect" data-label="merged-group-J1-x-" data-x="1.374" data-y="-1.995" x="156.92800000000003" y="360.47555555555556" width="22.400000000000006" height="19.911111111111154" fill="hsl(296, 100%, 50%, 0.2)" stroke="hsl(296, 100%, 50%, 1)" stroke-width="0.020089285714285712" />
138
+ </g>
139
+ <g>
140
+ <rect data-type="rect" data-label="schematic_component_0" data-x="6.250000000000001" data-y="-0.25" x="351.1111111111112" y="258.68" width="119.46666666666664" height="49.77777777777777" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
141
+ </g>
142
+ <g>
143
+ <rect data-type="rect" data-label="schematic_component_1" data-x="8.950000000000001" data-y="-2.345" x="490.488888888889" y="367.94222222222226" width="109.511111111111" height="39.82222222222225" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
144
+ </g>
145
+ <g>
146
+ <rect data-type="rect" data-label="" data-x="7.6240000000000006" data-y="-2.245" x="468.0391111111112" y="372.92" width="22.39999999999992" height="19.911111111111097" fill="rgba(255, 0, 0, 0.2)" stroke="black" stroke-width="0.020089285714285712" />
147
+ </g><text data-type="text" data-label="MergedNetLabelObstaclesSolver" data-x="1.3" data-y="0.78125" x="164.44444444444446" y="232.23555555555558" fill="black" font-size="14" font-family="sans-serif" text-anchor="middle" dominant-baseline="text-after-edge">MergedNetLabelObstaclesSolver</text><text data-type="text" data-label="SingleOverlapSolver" data-x="7.550000000000001" data-y="0.53125" x="475.5555555555556" y="244.68" fill="black" font-size="14" font-family="sans-serif" text-anchor="middle" dominant-baseline="text-after-edge">SingleOverlapSolver</text>
148
+ <g id="crosshair" style="display: none">
149
+ <line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
150
+ <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>
151
+ </g>
152
+ <script>
153
+ <![CDATA[
154
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
155
+ const svg = e.currentTarget;
156
+ const rect = svg.getBoundingClientRect();
157
+ const x = e.clientX - rect.left;
158
+ const y = e.clientY - rect.top;
159
+ const crosshair = svg.getElementById('crosshair');
160
+ const h = svg.getElementById('crosshair-h');
161
+ const v = svg.getElementById('crosshair-v');
162
+ const coords = svg.getElementById('coordinates');
163
+
164
+ crosshair.style.display = 'block';
165
+ h.setAttribute('x1', '0');
166
+ h.setAttribute('x2', '640');
167
+ h.setAttribute('y1', y);
168
+ h.setAttribute('y2', y);
169
+ v.setAttribute('x1', x);
170
+ v.setAttribute('x2', x);
171
+ v.setAttribute('y1', '0');
172
+ v.setAttribute('y2', '640');
173
+
174
+ // Calculate real coordinates using inverse transformation
175
+ const matrix = {
176
+ "a": 49.77777777777778,
177
+ "c": 0,
178
+ "e": 99.73333333333335,
179
+ "b": 0,
180
+ "d": -49.77777777777778,
181
+ "f": 271.12444444444446
182
+ };
183
+ // Manually invert and apply the affine transform
184
+ // Since we only use translate and scale, we can directly compute:
185
+ // x' = (x - tx) / sx
186
+ // y' = (y - ty) / sy
187
+ const sx = matrix.a;
188
+ const sy = matrix.d;
189
+ const tx = matrix.e;
190
+ const ty = matrix.f;
191
+ const realPoint = {
192
+ x: (x - tx) / sx,
193
+ y: (y - ty) / sy // Flip y back since we used negative scale
194
+ }
195
+
196
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
197
+ coords.setAttribute('x', (x + 5).toString());
198
+ coords.setAttribute('y', (y - 5).toString());
199
+ });
200
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
201
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
202
+ });
203
+ ]]>
204
+ </script>
205
+ </svg>
@@ -0,0 +1,184 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="100%" height="100%" fill="white" />
3
+ <g>
4
+ <circle data-type="point" data-label="U1.1
5
+ x+" data-x="1.2000000000000002" data-y="-0.30000000000000004" cx="159.4666666666667" cy="292.28000000000003" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
6
+ </g>
7
+ <g>
8
+ <circle data-type="point" data-label="U1.2
9
+ x-" data-x="-1.2000000000000002" data-y="-0.30000000000000004" cx="40.00000000000001" cy="292.28000000000003" r="3" fill="hsl(320, 100%, 50%, 0.8)" />
10
+ </g>
11
+ <g>
12
+ <circle data-type="point" data-label="U1.3
13
+ x+" data-x="1.2000000000000002" data-y="0.09999999999999998" cx="159.4666666666667" cy="272.36888888888893" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
14
+ </g>
15
+ <g>
16
+ <circle data-type="point" data-label="U1.4
17
+ x-" data-x="-1.2000000000000002" data-y="0.30000000000000004" cx="40.00000000000001" cy="262.41333333333336" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
18
+ </g>
19
+ <g>
20
+ <circle data-type="point" data-label="U1.5
21
+ x-" data-x="-1.2000000000000002" data-y="0.10000000000000003" cx="40.00000000000001" cy="272.36888888888893" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
22
+ </g>
23
+ <g>
24
+ <circle data-type="point" data-label="U1.6
25
+ x-" data-x="-1.2000000000000002" data-y="-0.09999999999999998" cx="40.00000000000001" cy="282.32444444444445" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
26
+ </g>
27
+ <g>
28
+ <circle data-type="point" data-label="U1.7
29
+ x+" data-x="1.2000000000000002" data-y="-0.10000000000000003" cx="159.4666666666667" cy="282.32444444444445" r="3" fill="hsl(325, 100%, 50%, 0.8)" />
30
+ </g>
31
+ <g>
32
+ <circle data-type="point" data-label="U1.8
33
+ x+" data-x="1.2000000000000002" data-y="0.30000000000000004" cx="159.4666666666667" cy="262.41333333333336" r="3" fill="hsl(326, 100%, 50%, 0.8)" />
34
+ </g>
35
+ <g>
36
+ <circle data-type="point" data-label="J1.1
37
+ x-" data-x="1.6" data-y="-1.895" cx="179.3777777777778" cy="371.6755555555556" r="3" fill="hsl(218, 100%, 50%, 0.8)" />
38
+ </g>
39
+ <g>
40
+ <circle data-type="point" data-label="J1.2
41
+ x-" data-x="1.6" data-y="-2.095" cx="179.3777777777778" cy="381.6311111111112" r="3" fill="hsl(219, 100%, 50%, 0.8)" />
42
+ </g>
43
+ <g>
44
+ <circle data-type="point" data-label="J1.3
45
+ x-" data-x="1.6" data-y="-2.295" cx="179.3777777777778" cy="391.5866666666667" r="3" fill="hsl(220, 100%, 50%, 0.8)" />
46
+ </g>
47
+ <g>
48
+ <circle data-type="point" data-label="U1.1
49
+ x+" data-x="7.450000000000001" data-y="-0.30000000000000004" cx="470.57777777777784" cy="292.28000000000003" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
50
+ </g>
51
+ <g>
52
+ <circle data-type="point" data-label="U1.2
53
+ x-" data-x="5.050000000000001" data-y="-0.30000000000000004" cx="351.1111111111112" cy="292.28000000000003" r="3" fill="hsl(320, 100%, 50%, 0.8)" />
54
+ </g>
55
+ <g>
56
+ <circle data-type="point" data-label="U1.3
57
+ x+" data-x="7.450000000000001" data-y="0.09999999999999998" cx="470.57777777777784" cy="272.36888888888893" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
58
+ </g>
59
+ <g>
60
+ <circle data-type="point" data-label="U1.4
61
+ x-" data-x="5.050000000000001" data-y="0.30000000000000004" cx="351.1111111111112" cy="262.41333333333336" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
62
+ </g>
63
+ <g>
64
+ <circle data-type="point" data-label="U1.5
65
+ x-" data-x="5.050000000000001" data-y="0.10000000000000003" cx="351.1111111111112" cy="272.36888888888893" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
66
+ </g>
67
+ <g>
68
+ <circle data-type="point" data-label="U1.6
69
+ x-" data-x="5.050000000000001" data-y="-0.09999999999999998" cx="351.1111111111112" cy="282.32444444444445" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
70
+ </g>
71
+ <g>
72
+ <circle data-type="point" data-label="U1.7
73
+ x+" data-x="7.450000000000001" data-y="-0.10000000000000003" cx="470.57777777777784" cy="282.32444444444445" r="3" fill="hsl(325, 100%, 50%, 0.8)" />
74
+ </g>
75
+ <g>
76
+ <circle data-type="point" data-label="U1.8
77
+ x+" data-x="7.450000000000001" data-y="0.30000000000000004" cx="470.57777777777784" cy="262.41333333333336" r="3" fill="hsl(326, 100%, 50%, 0.8)" />
78
+ </g>
79
+ <g>
80
+ <circle data-type="point" data-label="J1.1
81
+ x-" data-x="7.850000000000001" data-y="-1.895" cx="490.488888888889" cy="371.6755555555556" r="3" fill="hsl(218, 100%, 50%, 0.8)" />
82
+ </g>
83
+ <g>
84
+ <circle data-type="point" data-label="J1.2
85
+ x-" data-x="7.850000000000001" data-y="-2.095" cx="490.488888888889" cy="381.6311111111112" r="3" fill="hsl(219, 100%, 50%, 0.8)" />
86
+ </g>
87
+ <g>
88
+ <circle data-type="point" data-label="J1.3
89
+ x-" data-x="7.850000000000001" data-y="-2.295" cx="490.488888888889" cy="391.5866666666667" r="3" fill="hsl(220, 100%, 50%, 0.8)" />
90
+ </g>
91
+ <g>
92
+ <polyline data-points="1.2000000000000002,-0.30000000000000004 1.6,-2.295" data-type="line" data-label="" points="159.4666666666667,292.28000000000003 179.3777777777778,391.5866666666667" fill="none" stroke="hsl(157, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
93
+ </g>
94
+ <g>
95
+ <polyline data-points="1.2000000000000002,0.30000000000000004 1.6,-1.895" data-type="line" data-label="" points="159.4666666666667,262.41333333333336 179.3777777777778,371.6755555555556" fill="none" stroke="hsl(190, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
96
+ </g>
97
+ <g>
98
+ <polyline data-points="1.2000000000000002,-0.30000000000000004 1.4000000000000001,-0.30000000000000004 1.4000000000000001,-1.2974999999999999 1.4000000000000001,-2.295 1.6,-2.295" data-type="line" data-label="" points="159.4666666666667,292.28000000000003 169.42222222222225,292.28000000000003 169.42222222222225,341.93333333333334 169.42222222222225,391.5866666666667 179.3777777777778,391.5866666666667" fill="none" stroke="red" stroke-width="1" stroke-dasharray="4 4" />
99
+ </g>
100
+ <g>
101
+ <polyline data-points="1.2000000000000002,-0.30000000000000004 1.4000000000000001,-0.30000000000000004 1.4000000000000001,-1.6949999999999998 1.049,-1.6949999999999998 1.049,-2.2950000000000004 1.6,-2.295" data-type="line" data-label="" points="159.4666666666667,292.28000000000003 169.42222222222225,292.28000000000003 169.42222222222225,361.72 151.95022222222224,361.72 151.95022222222224,391.5866666666667 179.3777777777778,391.5866666666667" fill="none" stroke="green" stroke-width="1" />
102
+ </g>
103
+ <g>
104
+ <polyline data-points="7.450000000000001,-0.30000000000000004 7.850000000000001,-2.295" data-type="line" data-label="" points="470.57777777777784,292.28000000000003 490.488888888889,391.5866666666667" fill="none" stroke="hsl(157, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
105
+ </g>
106
+ <g>
107
+ <polyline data-points="7.450000000000001,0.30000000000000004 7.850000000000001,-1.895" data-type="line" data-label="" points="470.57777777777784,262.41333333333336 490.488888888889,371.6755555555556" fill="none" stroke="hsl(190, 100%, 50%, 0.1)" stroke-width="1" stroke-dasharray="4 2" />
108
+ </g>
109
+ <g>
110
+ <polyline data-points="7.450000000000001,-0.30000000000000004 7.650000000000001,-0.30000000000000004 7.650000000000001,-1.2975000000000003 7.299000000000001,-1.2975000000000003 7.299000000000001,-2.2950000000000004 7.850000000000001,-2.295" data-type="line" data-label="" points="470.57777777777784,292.28000000000003 480.5333333333334,292.28000000000003 480.5333333333334,341.9333333333334 463.06133333333344,341.9333333333334 463.06133333333344,391.5866666666667 490.488888888889,391.5866666666667" fill="none" stroke="blue" stroke-width="1" />
111
+ </g>
112
+ <g>
113
+ <rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="40.00000000000001" y="252.4577777777778" width="119.4666666666667" height="49.7777777777778" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
114
+ </g>
115
+ <g>
116
+ <rect data-type="rect" data-label="schematic_component_1" data-x="2.7" data-y="-2.095" x="179.3777777777778" y="361.72" width="109.51111111111112" height="39.822222222222194" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
117
+ </g>
118
+ <g>
119
+ <rect data-type="rect" data-label="" data-x="1.374" data-y="-1.995" x="156.92800000000003" y="366.6977777777778" width="22.400000000000006" height="19.911111111111154" fill="rgba(255, 0, 0, 0.2)" stroke="black" stroke-width="0.020089285714285712" />
120
+ </g>
121
+ <g>
122
+ <rect data-type="rect" data-label="schematic_component_0" data-x="6.250000000000001" data-y="0" x="351.1111111111112" y="252.4577777777778" width="119.46666666666664" height="49.7777777777778" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
123
+ </g>
124
+ <g>
125
+ <rect data-type="rect" data-label="schematic_component_1" data-x="8.950000000000001" data-y="-2.095" x="490.488888888889" y="361.72" width="109.511111111111" height="39.822222222222194" fill="hsl(24, 100%, 50%, 0.1)" stroke="black" stroke-width="0.020089285714285712" />
126
+ </g><text data-type="text" data-label="SingleOverlapSolver" data-x="1.3" data-y="0.78125" x="164.44444444444446" y="238.4577777777778" fill="black" font-size="14" font-family="sans-serif" text-anchor="middle" dominant-baseline="text-after-edge">SingleOverlapSolver</text><text data-type="text" data-label="TraceCleanupSolver" data-x="7.550000000000001" data-y="0.78125" x="475.5555555555556" y="238.4577777777778" fill="black" font-size="14" font-family="sans-serif" text-anchor="middle" dominant-baseline="text-after-edge">TraceCleanupSolver</text>
127
+ <g id="crosshair" style="display: none">
128
+ <line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
129
+ <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>
130
+ </g>
131
+ <script>
132
+ <![CDATA[
133
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
134
+ const svg = e.currentTarget;
135
+ const rect = svg.getBoundingClientRect();
136
+ const x = e.clientX - rect.left;
137
+ const y = e.clientY - rect.top;
138
+ const crosshair = svg.getElementById('crosshair');
139
+ const h = svg.getElementById('crosshair-h');
140
+ const v = svg.getElementById('crosshair-v');
141
+ const coords = svg.getElementById('coordinates');
142
+
143
+ crosshair.style.display = 'block';
144
+ h.setAttribute('x1', '0');
145
+ h.setAttribute('x2', '640');
146
+ h.setAttribute('y1', y);
147
+ h.setAttribute('y2', y);
148
+ v.setAttribute('x1', x);
149
+ v.setAttribute('x2', x);
150
+ v.setAttribute('y1', '0');
151
+ v.setAttribute('y2', '640');
152
+
153
+ // Calculate real coordinates using inverse transformation
154
+ const matrix = {
155
+ "a": 49.77777777777778,
156
+ "c": 0,
157
+ "e": 99.73333333333335,
158
+ "b": 0,
159
+ "d": -49.77777777777778,
160
+ "f": 277.3466666666667
161
+ };
162
+ // Manually invert and apply the affine transform
163
+ // Since we only use translate and scale, we can directly compute:
164
+ // x' = (x - tx) / sx
165
+ // y' = (y - ty) / sy
166
+ const sx = matrix.a;
167
+ const sy = matrix.d;
168
+ const tx = matrix.e;
169
+ const ty = matrix.f;
170
+ const realPoint = {
171
+ x: (x - tx) / sx,
172
+ y: (y - ty) / sy // Flip y back since we used negative scale
173
+ }
174
+
175
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
176
+ coords.setAttribute('x', (x + 5).toString());
177
+ coords.setAttribute('y', (y - 5).toString());
178
+ });
179
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
180
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
181
+ });
182
+ ]]>
183
+ </script>
184
+ </svg>
@@ -0,0 +1,29 @@
1
+ import { MergedNetLabelObstacleSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver"
2
+ import { expect } from "bun:test"
3
+ import { test } from "bun:test"
4
+ import {
5
+ getSvgFromGraphicsObject,
6
+ stackGraphicsHorizontally,
7
+ } from "graphics-debug"
8
+ import { NetLabelPlacementSolver } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
9
+ import inputData from "../../../assets/1.input.json"
10
+
11
+ test("NetLabelPlacementSolver-to-MergedNetLabelObstacles snapshot", () => {
12
+ const solver1 = new MergedNetLabelObstacleSolver(
13
+ inputData.mergedNetLabelObstacleSolver as any,
14
+ )
15
+ const solver2 = new NetLabelPlacementSolver(
16
+ inputData.netLabelPlacementSolver as any,
17
+ )
18
+ solver1.solve()
19
+ solver2.solve()
20
+ const sideBySide = getSvgFromGraphicsObject(
21
+ stackGraphicsHorizontally([solver2.visualize(), solver1.visualize()], {
22
+ titles: ["NetLabelPlacementSolver", "MergedNetLabelObstacles"],
23
+ }),
24
+ {
25
+ backgroundColor: "white",
26
+ },
27
+ )
28
+ expect(sideBySide).toMatchSvgSnapshot(import.meta.path)
29
+ })
@@ -0,0 +1,27 @@
1
+ import { MergedNetLabelObstacleSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver"
2
+ import { expect } from "bun:test"
3
+ import { test } from "bun:test"
4
+ import {
5
+ getSvgFromGraphicsObject,
6
+ stackGraphicsHorizontally,
7
+ } from "graphics-debug"
8
+ import { SingleOverlapSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver"
9
+ import inputData from "../../../assets/2.input.json"
10
+
11
+ test("MergedNetLabelObstaclesSolver-to-SingleOverlapSolver snapshot", () => {
12
+ const solver1 = new MergedNetLabelObstacleSolver(
13
+ inputData.mergedNetLabelObstacleSolver as any,
14
+ )
15
+ const solver2 = new SingleOverlapSolver(inputData.singleOverlapSolver as any)
16
+ solver1.solve()
17
+ solver2.solve()
18
+ const sideBySide = getSvgFromGraphicsObject(
19
+ stackGraphicsHorizontally([solver1.visualize(), solver2.visualize()], {
20
+ titles: ["MergedNetLabelObstaclesSolver", "SingleOverlapSolver"],
21
+ }),
22
+ {
23
+ backgroundColor: "white",
24
+ },
25
+ )
26
+ expect(sideBySide).toMatchSvgSnapshot(import.meta.path)
27
+ })
@@ -0,0 +1,39 @@
1
+ import { expect } from "bun:test"
2
+ import { test } from "bun:test"
3
+ import {
4
+ getSvgFromGraphicsObject,
5
+ stackGraphicsHorizontally,
6
+ } from "graphics-debug"
7
+ import { SingleOverlapSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver"
8
+ import { TraceCleanupSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/TraceCleanupSolver/TraceCleanupSolver"
9
+ import inputData from "../../../assets/3.input.json"
10
+
11
+ test("SingleOverlapSolver-to-TraceCleanupSolver snapshot", () => {
12
+ // Convert targetTraceIds to Set
13
+ // @ts-expect-error
14
+ inputData.traceCleanupSolver.targetTraceIds = new Set(
15
+ inputData.traceCleanupSolver.targetTraceIds,
16
+ )
17
+
18
+ // Convert mergedLabelNetIdMap arrays to Sets
19
+ // @ts-expect-error
20
+ inputData.traceCleanupSolver.mergedLabelNetIdMap = Object.fromEntries(
21
+ Object.entries(inputData.traceCleanupSolver.mergedLabelNetIdMap).map(
22
+ ([key, value]) => [key, new Set(value)],
23
+ ),
24
+ )
25
+
26
+ const solver1 = new TraceCleanupSolver(inputData.traceCleanupSolver as any)
27
+ const solver2 = new SingleOverlapSolver(inputData.singleOverlapSolver as any)
28
+ solver1.solve()
29
+ solver2.solve()
30
+ const sideBySide = getSvgFromGraphicsObject(
31
+ stackGraphicsHorizontally([solver2.visualize(), solver1.visualize()], {
32
+ titles: ["SingleOverlapSolver", "TraceCleanupSolver"],
33
+ }),
34
+ {
35
+ backgroundColor: "white",
36
+ },
37
+ )
38
+ expect(sideBySide).toMatchSvgSnapshot(import.meta.path)
39
+ })
@@ -0,0 +1,14 @@
1
+ import { MergedNetLabelObstacleSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/LabelMergingSolver/LabelMergingSolver"
2
+ import { expect } from "bun:test"
3
+ import { test } from "bun:test"
4
+ import inputData from "../../../assets/MergedNetLabelObstacles.test.input.json"
5
+
6
+ test("LabelMergingSolver snapshot", () => {
7
+ const solver = new MergedNetLabelObstacleSolver({
8
+ netLabelPlacements: inputData.netLabelPlacements as any,
9
+ inputProblem: inputData.inputProblem as any,
10
+ traces: inputData.traces as any,
11
+ })
12
+ solver.solve()
13
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
14
+ })
@@ -0,0 +1,20 @@
1
+ import { OverlapAvoidanceStepSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/OverlapAvoidanceStepSolver/OverlapAvoidanceStepSolver"
2
+ import { expect } from "bun:test"
3
+ import { test } from "bun:test"
4
+ import inputData from "../../../assets/OverlapAvoidanceStepSolver.test.input.json"
5
+
6
+ test("OverlapAvoidanceStepSolver snapshot", () => {
7
+ const solver = new OverlapAvoidanceStepSolver({
8
+ inputProblem: inputData.problem as any,
9
+ traces: inputData.traces as any,
10
+ netLabelPlacements: inputData.netLabelPlacements as any,
11
+ mergedLabelNetIdMap: Object.fromEntries(
12
+ Object.entries(inputData.mergedLabelNetIdMap).map(([k, v]) => [
13
+ k,
14
+ new Set(v as any),
15
+ ]),
16
+ ),
17
+ } as any)
18
+ solver.solve()
19
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
20
+ })
@@ -0,0 +1,10 @@
1
+ import { expect } from "bun:test"
2
+ import { test } from "bun:test"
3
+ import { SingleOverlapSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/SingleOverlapSolver/SingleOverlapSolver"
4
+ import inputData from "../../../assets/SingleOverlapSolver.test.input.json"
5
+
6
+ test("SingleOverlapSolver snapshot", () => {
7
+ const solver = new SingleOverlapSolver(inputData as any)
8
+ solver.solve()
9
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
10
+ })
@@ -0,0 +1,19 @@
1
+ import { expect } from "bun:test"
2
+ import { test } from "bun:test"
3
+ import { TraceCleanupSolver } from "lib/solvers/TraceLabelOverlapAvoidanceSolver/sub-solvers/TraceCleanupSolver/TraceCleanupSolver"
4
+ import inputData from "../../../assets/TraceCleanupSolver.test.input.json"
5
+
6
+ test("TraceCleanupSolver snapshot", () => {
7
+ const solver = new TraceCleanupSolver({
8
+ ...inputData,
9
+ targetTraceIds: new Set(inputData.targetTraceIds),
10
+ mergedLabelNetIdMap: Object.fromEntries(
11
+ Object.entries(inputData.mergedLabelNetIdMap).map(([k, v]) => [
12
+ k,
13
+ new Set(v as any),
14
+ ]),
15
+ ),
16
+ } as any)
17
+ solver.solve()
18
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
19
+ })