@tscircuit/schematic-trace-solver 0.0.69 → 0.0.71
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.
- package/dist/index.js +38 -7
- package/lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts +45 -10
- package/lib/utils/arePinsInDifferentSchematicSections.ts +5 -1
- package/package.json +1 -1
- package/site/examples/example42.page.tsx +4 -0
- package/tests/assets/example42.json +139 -0
- package/tests/examples/__snapshots__/example42.snap.svg +195 -0
- package/tests/examples/example42.test.ts +12 -0
package/dist/index.js
CHANGED
|
@@ -322,7 +322,7 @@ var arePinsInDifferentSchematicSections = (inputProblem, p1, p2) => {
|
|
|
322
322
|
if (sectionByChipId.size === 0) return false;
|
|
323
323
|
const s1 = getSectionNameForPin(sectionByChipId, sectionByPinId, p1);
|
|
324
324
|
const s2 = getSectionNameForPin(sectionByChipId, sectionByPinId, p2);
|
|
325
|
-
return
|
|
325
|
+
return s1 !== s2;
|
|
326
326
|
};
|
|
327
327
|
|
|
328
328
|
// lib/solvers/SchematicTracePipelineSolver/visualizeInputProblem.ts
|
|
@@ -1234,12 +1234,43 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
1234
1234
|
}) {
|
|
1235
1235
|
const blockingCollisions = this.getBlockingCollisions({ group, offset });
|
|
1236
1236
|
if (blockingCollisions.length === 0) return offset;
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
(
|
|
1242
|
-
|
|
1237
|
+
const crossesThroughObstacle = (candidateOffset) => blockingCollisions.some(({ start, isVertical: isVertical4, obstacle }) => {
|
|
1238
|
+
let orig;
|
|
1239
|
+
let min;
|
|
1240
|
+
let max;
|
|
1241
|
+
if (isVertical4) {
|
|
1242
|
+
orig = start.x;
|
|
1243
|
+
min = obstacle.minX;
|
|
1244
|
+
max = obstacle.maxX;
|
|
1245
|
+
} else {
|
|
1246
|
+
orig = start.y;
|
|
1247
|
+
min = obstacle.minY;
|
|
1248
|
+
max = obstacle.maxY;
|
|
1249
|
+
}
|
|
1250
|
+
const next = orig + candidateOffset;
|
|
1251
|
+
return orig <= min + EPS4 && next >= max - EPS4 || orig >= max - EPS4 && next <= min + EPS4;
|
|
1252
|
+
});
|
|
1253
|
+
const edges = blockingCollisions.map(({ start, isVertical: isVertical4, obstacle }) => {
|
|
1254
|
+
if (isVertical4) {
|
|
1255
|
+
return {
|
|
1256
|
+
coord: start.x,
|
|
1257
|
+
lowEdge: obstacle.minX,
|
|
1258
|
+
highEdge: obstacle.maxX
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
return { coord: start.y, lowEdge: obstacle.minY, highEdge: obstacle.maxY };
|
|
1262
|
+
});
|
|
1263
|
+
const bestCandidate = (clearance) => {
|
|
1264
|
+
const candidates = edges.flatMap(({ coord, lowEdge, highEdge }) => [
|
|
1265
|
+
lowEdge - coord - clearance,
|
|
1266
|
+
highEdge - coord + clearance
|
|
1267
|
+
]);
|
|
1268
|
+
return candidates.filter((candidateOffset) => !crossesThroughObstacle(candidateOffset)).filter(
|
|
1269
|
+
(candidateOffset) => this.getBlockingCollisions({ group, offset: candidateOffset }).length === 0
|
|
1270
|
+
).sort((a, b) => Math.abs(a - offset) - Math.abs(b - offset))[0];
|
|
1271
|
+
};
|
|
1272
|
+
const EDGE_MARGIN = this.SHIFT_DISTANCE / 10;
|
|
1273
|
+
return bestCandidate(this.SHIFT_DISTANCE) ?? bestCandidate(EDGE_MARGIN) ?? offset;
|
|
1243
1274
|
}
|
|
1244
1275
|
getBlockingCollisions({
|
|
1245
1276
|
group,
|
package/lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
CHANGED
|
@@ -180,21 +180,56 @@ export class TraceOverlapIssueSolver extends BaseSolver {
|
|
|
180
180
|
const blockingCollisions = this.getBlockingCollisions({ group, offset })
|
|
181
181
|
if (blockingCollisions.length === 0) return offset
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
blockingCollisions
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
183
|
+
const crossesThroughObstacle = (candidateOffset: number) =>
|
|
184
|
+
blockingCollisions.some(({ start, isVertical, obstacle }) => {
|
|
185
|
+
let orig: number
|
|
186
|
+
let min: number
|
|
187
|
+
let max: number
|
|
188
|
+
if (isVertical) {
|
|
189
|
+
orig = start.x
|
|
190
|
+
min = obstacle.minX
|
|
191
|
+
max = obstacle.maxX
|
|
192
|
+
} else {
|
|
193
|
+
orig = start.y
|
|
194
|
+
min = obstacle.minY
|
|
195
|
+
max = obstacle.maxY
|
|
196
|
+
}
|
|
197
|
+
const next = orig + candidateOffset
|
|
198
|
+
return (
|
|
199
|
+
(orig <= min + EPS && next >= max - EPS) ||
|
|
200
|
+
(orig >= max - EPS && next <= min + EPS)
|
|
201
|
+
)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
const edges = blockingCollisions.map(({ start, isVertical, obstacle }) => {
|
|
205
|
+
if (isVertical) {
|
|
206
|
+
return {
|
|
207
|
+
coord: start.x,
|
|
208
|
+
lowEdge: obstacle.minX,
|
|
209
|
+
highEdge: obstacle.maxX,
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return { coord: start.y, lowEdge: obstacle.minY, highEdge: obstacle.maxY }
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
const bestCandidate = (clearance: number) => {
|
|
216
|
+
const candidates = edges.flatMap(({ coord, lowEdge, highEdge }) => [
|
|
217
|
+
lowEdge - coord - clearance,
|
|
218
|
+
highEdge - coord + clearance,
|
|
219
|
+
])
|
|
220
|
+
return candidates
|
|
221
|
+
.filter((candidateOffset) => !crossesThroughObstacle(candidateOffset))
|
|
191
222
|
.filter(
|
|
192
223
|
(candidateOffset) =>
|
|
193
224
|
this.getBlockingCollisions({ group, offset: candidateOffset })
|
|
194
225
|
.length === 0,
|
|
195
226
|
)
|
|
196
|
-
.sort((a, b) => Math.abs(a - offset) - Math.abs(b - offset))[0]
|
|
197
|
-
|
|
227
|
+
.sort((a, b) => Math.abs(a - offset) - Math.abs(b - offset))[0]
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const EDGE_MARGIN = this.SHIFT_DISTANCE / 10
|
|
231
|
+
return (
|
|
232
|
+
bestCandidate(this.SHIFT_DISTANCE) ?? bestCandidate(EDGE_MARGIN) ?? offset
|
|
198
233
|
)
|
|
199
234
|
}
|
|
200
235
|
|
|
@@ -32,8 +32,12 @@ export const arePinsInDifferentSchematicSections = (
|
|
|
32
32
|
|
|
33
33
|
if (sectionByChipId.size === 0) return false
|
|
34
34
|
|
|
35
|
+
// Pins without an explicit section belong to an implicit "no-section"
|
|
36
|
+
// section. Traces must not cross between sections, so a sectioned pin and an
|
|
37
|
+
// unsectioned pin (or two differently-named sections) count as different.
|
|
38
|
+
// `undefined !== undefined` is false, so two unsectioned pins compare equal.
|
|
35
39
|
const s1 = getSectionNameForPin(sectionByChipId, sectionByPinId, p1)
|
|
36
40
|
const s2 = getSectionNameForPin(sectionByChipId, sectionByPinId, p2)
|
|
37
41
|
|
|
38
|
-
return
|
|
42
|
+
return s1 !== s2
|
|
39
43
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "schematic_component_16",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": 0,
|
|
7
|
+
"y": 0
|
|
8
|
+
},
|
|
9
|
+
"width": 4.4,
|
|
10
|
+
"height": 2,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "U3.1",
|
|
14
|
+
"x": 2.6,
|
|
15
|
+
"y": 0.8499999999999999
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pinId": "U3.2",
|
|
19
|
+
"x": 2.6,
|
|
20
|
+
"y": 0.6499999999999999
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"pinId": "U3.3",
|
|
24
|
+
"x": 2.6,
|
|
25
|
+
"y": 0.44999999999999996
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"pinId": "U3.4",
|
|
29
|
+
"x": 2.6,
|
|
30
|
+
"y": 0.10000000000000009
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"pinId": "U3.5",
|
|
34
|
+
"x": 2.6,
|
|
35
|
+
"y": -0.09999999999999987
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"pinId": "U3.6",
|
|
39
|
+
"x": 2.6,
|
|
40
|
+
"y": -0.44999999999999984
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"pinId": "U3.7",
|
|
44
|
+
"x": 2.6,
|
|
45
|
+
"y": -0.6499999999999999
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"pinId": "U3.8",
|
|
49
|
+
"x": 2.6,
|
|
50
|
+
"y": -0.8499999999999999
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"chipId": "schematic_component_17",
|
|
56
|
+
"center": {
|
|
57
|
+
"x": 3.2,
|
|
58
|
+
"y": -1.4
|
|
59
|
+
},
|
|
60
|
+
"width": 1.1,
|
|
61
|
+
"height": 0.7789106999999986,
|
|
62
|
+
"pins": [
|
|
63
|
+
{
|
|
64
|
+
"pinId": "R8.1",
|
|
65
|
+
"x": 2.6500000000000004,
|
|
66
|
+
"y": -1.4
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"pinId": "R8.2",
|
|
70
|
+
"x": 3.75,
|
|
71
|
+
"y": -1.4
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"chipId": "schematic_component_18",
|
|
77
|
+
"center": {
|
|
78
|
+
"x": 3.2,
|
|
79
|
+
"y": -2.4
|
|
80
|
+
},
|
|
81
|
+
"width": 1.1,
|
|
82
|
+
"height": 0.7789106999999986,
|
|
83
|
+
"pins": [
|
|
84
|
+
{
|
|
85
|
+
"pinId": "R9.1",
|
|
86
|
+
"x": 2.6500000000000004,
|
|
87
|
+
"y": -2.4
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"pinId": "R9.2",
|
|
91
|
+
"x": 3.75,
|
|
92
|
+
"y": -2.4
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"directConnections": [],
|
|
98
|
+
"netConnections": [
|
|
99
|
+
{
|
|
100
|
+
"netId": "GND",
|
|
101
|
+
"pinIds": ["U3.8", "R8.2", "R9.2"],
|
|
102
|
+
"netLabelWidth": 0.48
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"netId": "D_MINUS",
|
|
106
|
+
"pinIds": ["U3.3"],
|
|
107
|
+
"netLabelWidth": 0.96
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"netId": "D_PLUS",
|
|
111
|
+
"pinIds": ["U3.2"],
|
|
112
|
+
"netLabelWidth": 0.84
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"netId": "VBUS",
|
|
116
|
+
"pinIds": ["U3.1"],
|
|
117
|
+
"netLabelWidth": 0.6
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"netId": "CC1",
|
|
121
|
+
"pinIds": ["U3.4", "R8.1"],
|
|
122
|
+
"netLabelWidth": 0.48
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"netId": "CC2",
|
|
126
|
+
"pinIds": ["U3.5", "R9.1"],
|
|
127
|
+
"netLabelWidth": 0.48
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"availableNetLabelOrientations": {
|
|
131
|
+
"D_MINUS": ["x-", "x+"],
|
|
132
|
+
"D_PLUS": ["x-", "x+"],
|
|
133
|
+
"GND": ["y-"],
|
|
134
|
+
"VBUS": ["y+"],
|
|
135
|
+
"CC1": ["x-", "x+"],
|
|
136
|
+
"CC2": ["x-", "x+"]
|
|
137
|
+
},
|
|
138
|
+
"maxMspPairDistance": 2.4
|
|
139
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
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="U3.1
|
|
5
|
+
x+" data-x="2.6" data-y="0.8499999999999999" cx="477.8947368421052" cy="194.5684210526316" r="3" fill="hsl(81, 100%, 50%, 0.8)" />
|
|
6
|
+
</g>
|
|
7
|
+
<g>
|
|
8
|
+
<circle data-type="point" data-label="U3.2
|
|
9
|
+
x+" data-x="2.6" data-y="0.6499999999999999" cx="477.8947368421052" cy="211.4105263157895" r="3" fill="hsl(82, 100%, 50%, 0.8)" />
|
|
10
|
+
</g>
|
|
11
|
+
<g>
|
|
12
|
+
<circle data-type="point" data-label="U3.3
|
|
13
|
+
x+" data-x="2.6" data-y="0.44999999999999996" cx="477.8947368421052" cy="228.2526315789474" r="3" fill="hsl(83, 100%, 50%, 0.8)" />
|
|
14
|
+
</g>
|
|
15
|
+
<g>
|
|
16
|
+
<circle data-type="point" data-label="U3.4
|
|
17
|
+
x+" data-x="2.6" data-y="0.10000000000000009" cx="477.8947368421052" cy="257.7263157894737" r="3" fill="hsl(84, 100%, 50%, 0.8)" />
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
<circle data-type="point" data-label="U3.5
|
|
21
|
+
x+" data-x="2.6" data-y="-0.09999999999999987" cx="477.8947368421052" cy="274.5684210526316" r="3" fill="hsl(85, 100%, 50%, 0.8)" />
|
|
22
|
+
</g>
|
|
23
|
+
<g>
|
|
24
|
+
<circle data-type="point" data-label="U3.6
|
|
25
|
+
x+" data-x="2.6" data-y="-0.44999999999999984" cx="477.8947368421052" cy="304.0421052631579" r="3" fill="hsl(86, 100%, 50%, 0.8)" />
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
<circle data-type="point" data-label="U3.7
|
|
29
|
+
x+" data-x="2.6" data-y="-0.6499999999999999" cx="477.8947368421052" cy="320.88421052631577" r="3" fill="hsl(87, 100%, 50%, 0.8)" />
|
|
30
|
+
</g>
|
|
31
|
+
<g>
|
|
32
|
+
<circle data-type="point" data-label="U3.8
|
|
33
|
+
x+" data-x="2.6" data-y="-0.8499999999999999" cx="477.8947368421052" cy="337.7263157894737" r="3" fill="hsl(88, 100%, 50%, 0.8)" />
|
|
34
|
+
</g>
|
|
35
|
+
<g>
|
|
36
|
+
<circle data-type="point" data-label="R8.1
|
|
37
|
+
x-" data-x="2.6500000000000004" data-y="-1.4" cx="482.1052631578947" cy="384.0421052631579" r="3" fill="hsl(113, 100%, 50%, 0.8)" />
|
|
38
|
+
</g>
|
|
39
|
+
<g>
|
|
40
|
+
<circle data-type="point" data-label="R8.2
|
|
41
|
+
x+" data-x="3.75" data-y="-1.4" cx="574.7368421052631" cy="384.0421052631579" r="3" fill="hsl(114, 100%, 50%, 0.8)" />
|
|
42
|
+
</g>
|
|
43
|
+
<g>
|
|
44
|
+
<circle data-type="point" data-label="R9.1
|
|
45
|
+
x-" data-x="2.6500000000000004" data-y="-2.4" cx="482.1052631578947" cy="468.25263157894733" r="3" fill="hsl(354, 100%, 50%, 0.8)" />
|
|
46
|
+
</g>
|
|
47
|
+
<g>
|
|
48
|
+
<circle data-type="point" data-label="R9.2
|
|
49
|
+
x+" data-x="3.75" data-y="-2.4" cx="574.7368421052631" cy="468.25263157894733" r="3" fill="hsl(355, 100%, 50%, 0.8)" />
|
|
50
|
+
</g>
|
|
51
|
+
<g>
|
|
52
|
+
<circle data-type="point" data-label="anchorPoint
|
|
53
|
+
orientation: y+" data-x="2.701" data-y="1.001" cx="486.4" cy="181.8526315789474" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
54
|
+
</g>
|
|
55
|
+
<g>
|
|
56
|
+
<circle data-type="point" data-label="anchorPoint
|
|
57
|
+
orientation: x+" data-x="2.6" data-y="0.6499999999999999" cx="477.8947368421052" cy="211.4105263157895" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
58
|
+
</g>
|
|
59
|
+
<g>
|
|
60
|
+
<circle data-type="point" data-label="anchorPoint
|
|
61
|
+
orientation: x+" data-x="2.6" data-y="0.44999999999999996" cx="477.8947368421052" cy="228.2526315789474" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
62
|
+
</g>
|
|
63
|
+
<g>
|
|
64
|
+
<circle data-type="point" data-label="anchorPoint
|
|
65
|
+
orientation: x+" data-x="2.61" data-y="0.10000000000000009" cx="478.7368421052631" cy="257.7263157894737" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
66
|
+
</g>
|
|
67
|
+
<g>
|
|
68
|
+
<circle data-type="point" data-label="anchorPoint
|
|
69
|
+
orientation: x+" data-x="2.6400000000000006" data-y="-0.09999999999999987" cx="481.2631578947369" cy="274.5684210526316" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
70
|
+
</g>
|
|
71
|
+
<g>
|
|
72
|
+
<circle data-type="point" data-label="anchorPoint
|
|
73
|
+
orientation: y-" data-x="3.95" data-y="-2.4" cx="591.578947368421" cy="468.25263157894733" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
74
|
+
</g>
|
|
75
|
+
<g>
|
|
76
|
+
<polyline data-points="2.6,-0.8499999999999999 3.75,-1.4" data-type="line" data-label="" points="477.8947368421052,337.7263157894737 574.7368421052631,384.0421052631579" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
77
|
+
</g>
|
|
78
|
+
<g>
|
|
79
|
+
<polyline data-points="2.6,-0.8499999999999999 3.75,-2.4" data-type="line" data-label="" points="477.8947368421052,337.7263157894737 574.7368421052631,468.25263157894733" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
80
|
+
</g>
|
|
81
|
+
<g>
|
|
82
|
+
<polyline data-points="3.75,-1.4 3.75,-2.4" data-type="line" data-label="" points="574.7368421052631,384.0421052631579 574.7368421052631,468.25263157894733" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
83
|
+
</g>
|
|
84
|
+
<g>
|
|
85
|
+
<polyline data-points="2.6,0.10000000000000009 2.6500000000000004,-1.4" data-type="line" data-label="" points="477.8947368421052,257.7263157894737 482.1052631578947,384.0421052631579" fill="none" stroke="hsl(273, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
86
|
+
</g>
|
|
87
|
+
<g>
|
|
88
|
+
<polyline data-points="2.6,-0.09999999999999987 2.6500000000000004,-2.4" data-type="line" data-label="" points="477.8947368421052,274.5684210526316 482.1052631578947,468.25263157894733" fill="none" stroke="hsl(274, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
89
|
+
</g>
|
|
90
|
+
<g>
|
|
91
|
+
<polyline data-points="3.75,-2.4 3.95,-2.4 3.95,-1.4 3.75,-1.4" data-type="line" data-label="" points="574.7368421052631,468.25263157894733 591.578947368421,468.25263157894733 591.578947368421,384.0421052631579 574.7368421052631,384.0421052631579" fill="none" stroke="purple" stroke-width="1" />
|
|
92
|
+
</g>
|
|
93
|
+
<g>
|
|
94
|
+
<polyline data-points="2.6,-0.8499999999999999 3.95,-0.8499999999999999 3.95,-1.4 3.75,-1.4" data-type="line" data-label="" points="477.8947368421052,337.7263157894737 591.578947368421,337.7263157894737 591.578947368421,384.0421052631579 574.7368421052631,384.0421052631579" fill="none" stroke="purple" stroke-width="1" />
|
|
95
|
+
</g>
|
|
96
|
+
<g>
|
|
97
|
+
<polyline data-points="2.6,0.10000000000000009 2.61,0.10000000000000009 2.61,-1.2 2.435,-1.2 2.435,-1.4 2.6500000000000004,-1.4" data-type="line" data-label="" points="477.8947368421052,257.7263157894737 478.7368421052631,257.7263157894737 478.7368421052631,367.2 463.99999999999994,367.2 463.99999999999994,384.0421052631579 482.1052631578947,384.0421052631579" fill="none" stroke="purple" stroke-width="1" />
|
|
98
|
+
</g>
|
|
99
|
+
<g>
|
|
100
|
+
<polyline data-points="2.6,-0.09999999999999987 2.6400000000000006,-0.09999999999999987 2.6400000000000006,-1.25 2.4650000000000007,-1.25 2.4650000000000007,-2.4 2.6500000000000004,-2.4" data-type="line" data-label="" points="477.8947368421052,274.5684210526316 481.2631578947369,274.5684210526316 481.2631578947369,371.41052631578947 466.5263157894737,371.41052631578947 466.5263157894737,468.25263157894733 482.1052631578947,468.25263157894733" fill="none" stroke="purple" stroke-width="1" />
|
|
101
|
+
</g>
|
|
102
|
+
<g>
|
|
103
|
+
<polyline data-points="2.6,0.8499999999999999 2.701,0.8499999999999999 2.701,1.001" data-type="line" data-label="" points="477.8947368421052,194.5684210526316 486.4,194.5684210526316 486.4,181.8526315789474" fill="none" stroke="purple" stroke-width="1" />
|
|
104
|
+
</g>
|
|
105
|
+
<g>
|
|
106
|
+
<rect data-type="rect" data-label="schematic_component_16" data-x="0" data-y="0" x="39.99999999999997" y="181.93684210526317" width="437.8947368421052" height="168.42105263157896" fill="hsl(320, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011875000000000002" />
|
|
107
|
+
</g>
|
|
108
|
+
<g>
|
|
109
|
+
<rect data-type="rect" data-label="schematic_component_17" data-x="3.2" data-y="-1.4" x="482.1052631578947" y="351.24586526315795" width="92.63157894736844" height="65.59247999999991" fill="hsl(320, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011875000000000002" />
|
|
110
|
+
</g>
|
|
111
|
+
<g>
|
|
112
|
+
<rect data-type="rect" data-label="schematic_component_18" data-x="3.2" data-y="-2.4" x="482.1052631578947" y="435.45639157894743" width="92.63157894736844" height="65.59247999999985" fill="hsl(320, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011875000000000002" />
|
|
113
|
+
</g>
|
|
114
|
+
<g>
|
|
115
|
+
<rect data-type="rect" data-label="netId: VBUS
|
|
116
|
+
globalConnNetId: connectivity_net3" data-x="2.701" data-y="1.301" x="477.978947368421" y="131.3263157894737" width="16.84210526315792" height="50.5263157894737" fill="#ef444466" stroke="#ef4444" stroke-width="0.011875000000000002" />
|
|
117
|
+
</g>
|
|
118
|
+
<g>
|
|
119
|
+
<rect data-type="rect" data-label="netId: D_PLUS
|
|
120
|
+
globalConnNetId: connectivity_net2" data-x="3.021" data-y="0.6499999999999999" x="477.978947368421" y="202.98947368421057" width="70.73684210526312" height="16.84210526315789" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011875000000000002" />
|
|
121
|
+
</g>
|
|
122
|
+
<g>
|
|
123
|
+
<rect data-type="rect" data-label="netId: D_MINUS
|
|
124
|
+
globalConnNetId: connectivity_net1" data-x="3.081" data-y="0.44999999999999996" x="477.978947368421" y="219.83157894736846" width="80.8421052631578" height="16.84210526315789" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011875000000000002" />
|
|
125
|
+
</g>
|
|
126
|
+
<g>
|
|
127
|
+
<rect data-type="rect" data-label="netId: CC1
|
|
128
|
+
globalConnNetId: connectivity_net4" data-x="2.8499999999999996" data-y="0.10000000000000009" x="478.73684210526307" y="249.30526315789476" width="40.421052631579016" height="16.84210526315789" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011875000000000002" />
|
|
129
|
+
</g>
|
|
130
|
+
<g>
|
|
131
|
+
<rect data-type="rect" data-label="netId: CC2
|
|
132
|
+
globalConnNetId: connectivity_net5" data-x="2.880000000000001" data-y="-0.09999999999999987" x="481.2631578947369" y="266.14736842105265" width="40.42105263157896" height="16.842105263157862" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011875000000000002" />
|
|
133
|
+
</g>
|
|
134
|
+
<g>
|
|
135
|
+
<rect data-type="rect" data-label="netId: GND
|
|
136
|
+
globalConnNetId: connectivity_net0" data-x="3.95" data-y="-2.6399999999999997" x="583.1578947368421" y="468.25263157894733" width="16.84210526315792" height="40.42105263157896" fill="#00000066" stroke="#000000" stroke-width="0.011875000000000002" />
|
|
137
|
+
</g>
|
|
138
|
+
<g id="crosshair" style="display: none">
|
|
139
|
+
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
140
|
+
<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>
|
|
141
|
+
</g>
|
|
142
|
+
<script>
|
|
143
|
+
<![CDATA[
|
|
144
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
145
|
+
const svg = e.currentTarget;
|
|
146
|
+
const rect = svg.getBoundingClientRect();
|
|
147
|
+
const x = e.clientX - rect.left;
|
|
148
|
+
const y = e.clientY - rect.top;
|
|
149
|
+
const crosshair = svg.getElementById('crosshair');
|
|
150
|
+
const h = svg.getElementById('crosshair-h');
|
|
151
|
+
const v = svg.getElementById('crosshair-v');
|
|
152
|
+
const coords = svg.getElementById('coordinates');
|
|
153
|
+
|
|
154
|
+
crosshair.style.display = 'block';
|
|
155
|
+
h.setAttribute('x1', '0');
|
|
156
|
+
h.setAttribute('x2', '640');
|
|
157
|
+
h.setAttribute('y1', y);
|
|
158
|
+
h.setAttribute('y2', y);
|
|
159
|
+
v.setAttribute('x1', x);
|
|
160
|
+
v.setAttribute('x2', x);
|
|
161
|
+
v.setAttribute('y1', '0');
|
|
162
|
+
v.setAttribute('y2', '640');
|
|
163
|
+
|
|
164
|
+
// Calculate real coordinates using inverse transformation
|
|
165
|
+
const matrix = {
|
|
166
|
+
"a": 84.21052631578947,
|
|
167
|
+
"c": 0,
|
|
168
|
+
"e": 258.9473684210526,
|
|
169
|
+
"b": 0,
|
|
170
|
+
"d": -84.21052631578947,
|
|
171
|
+
"f": 266.14736842105265
|
|
172
|
+
};
|
|
173
|
+
// Manually invert and apply the affine transform
|
|
174
|
+
// Since we only use translate and scale, we can directly compute:
|
|
175
|
+
// x' = (x - tx) / sx
|
|
176
|
+
// y' = (y - ty) / sy
|
|
177
|
+
const sx = matrix.a;
|
|
178
|
+
const sy = matrix.d;
|
|
179
|
+
const tx = matrix.e;
|
|
180
|
+
const ty = matrix.f;
|
|
181
|
+
const realPoint = {
|
|
182
|
+
x: (x - tx) / sx,
|
|
183
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
187
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
188
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
189
|
+
});
|
|
190
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
191
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
192
|
+
});
|
|
193
|
+
]]>
|
|
194
|
+
</script>
|
|
195
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { test, expect } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import inputProblem from "../assets/example42.json"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
|
|
6
|
+
test("example42", () => {
|
|
7
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
|
+
|
|
9
|
+
solver.solve()
|
|
10
|
+
|
|
11
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
12
|
+
})
|