@tscircuit/schematic-trace-solver 0.0.30 → 0.0.31
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 +78 -23
- package/lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts +27 -25
- package/lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/applyJogToTrace.ts +76 -0
- package/lib/solvers/TraceOverlapShiftSolver/TraceOverlapShiftSolver.ts +1 -1
- package/package.json +1 -1
- package/site/SchematicTracePipelineSolver/SchematicTracePipelineSolver02.page.tsx +177 -0
- package/tests/examples/__snapshots__/example11.snap.svg +1 -1
- package/tests/examples/__snapshots__/example16.snap.svg +195 -0
- package/tests/examples/example16.test.tsx +175 -0
package/dist/index.js
CHANGED
|
@@ -1137,6 +1137,64 @@ var SchematicTraceLinesSolver = class extends BaseSolver {
|
|
|
1137
1137
|
}
|
|
1138
1138
|
};
|
|
1139
1139
|
|
|
1140
|
+
// lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/applyJogToTrace.ts
|
|
1141
|
+
var applyJogToTerminalSegment = ({
|
|
1142
|
+
pts,
|
|
1143
|
+
segmentIndex: si,
|
|
1144
|
+
offset,
|
|
1145
|
+
JOG_SIZE,
|
|
1146
|
+
EPS: EPS2 = 1e-6
|
|
1147
|
+
}) => {
|
|
1148
|
+
if (si !== 0 && si !== pts.length - 2) return;
|
|
1149
|
+
const start = pts[si];
|
|
1150
|
+
const end = pts[si + 1];
|
|
1151
|
+
const isVertical = Math.abs(start.x - end.x) < EPS2;
|
|
1152
|
+
const isHorizontal = Math.abs(start.y - end.y) < EPS2;
|
|
1153
|
+
if (!isVertical && !isHorizontal) return;
|
|
1154
|
+
const segDir = isVertical ? end.y > start.y ? 1 : -1 : end.x > start.x ? 1 : -1;
|
|
1155
|
+
if (si === 0) {
|
|
1156
|
+
if (isVertical) {
|
|
1157
|
+
const jogY = start.y + segDir * JOG_SIZE;
|
|
1158
|
+
pts.splice(
|
|
1159
|
+
1,
|
|
1160
|
+
1,
|
|
1161
|
+
{ x: start.x, y: jogY },
|
|
1162
|
+
{ x: start.x + offset, y: jogY },
|
|
1163
|
+
{ x: end.x + offset, y: end.y }
|
|
1164
|
+
);
|
|
1165
|
+
} else {
|
|
1166
|
+
const jogX = start.x + segDir * JOG_SIZE;
|
|
1167
|
+
pts.splice(
|
|
1168
|
+
1,
|
|
1169
|
+
1,
|
|
1170
|
+
{ x: jogX, y: start.y },
|
|
1171
|
+
{ x: jogX, y: start.y + offset },
|
|
1172
|
+
{ x: end.x, y: end.y + offset }
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
} else {
|
|
1176
|
+
if (isVertical) {
|
|
1177
|
+
const jogY = end.y - segDir * JOG_SIZE;
|
|
1178
|
+
pts.splice(
|
|
1179
|
+
si,
|
|
1180
|
+
1,
|
|
1181
|
+
{ x: start.x + offset, y: start.y },
|
|
1182
|
+
{ x: end.x + offset, y: jogY },
|
|
1183
|
+
{ x: end.x, y: jogY }
|
|
1184
|
+
);
|
|
1185
|
+
} else {
|
|
1186
|
+
const jogX = end.x - segDir * JOG_SIZE;
|
|
1187
|
+
pts.splice(
|
|
1188
|
+
si,
|
|
1189
|
+
1,
|
|
1190
|
+
{ x: start.x, y: start.y + offset },
|
|
1191
|
+
{ x: jogX, y: end.y + offset },
|
|
1192
|
+
{ x: jogX, y: end.y }
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
};
|
|
1197
|
+
|
|
1140
1198
|
// lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
|
|
1141
1199
|
var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
1142
1200
|
overlappingTraceSegments;
|
|
@@ -1180,33 +1238,30 @@ var TraceOverlapIssueSolver = class extends BaseSolver {
|
|
|
1180
1238
|
const current = this.correctedTraceMap[original.mspPairId] ?? original;
|
|
1181
1239
|
const pts = current.tracePath.map((p) => ({ ...p }));
|
|
1182
1240
|
const segIdxs = Array.from(segIdxSet).sort((a, b) => a - b);
|
|
1183
|
-
const
|
|
1184
|
-
const
|
|
1185
|
-
for (const si of
|
|
1241
|
+
const segIdxsRev = Array.from(segIdxSet).sort((a, b) => a - b).reverse();
|
|
1242
|
+
const JOG_SIZE = this.SHIFT_DISTANCE;
|
|
1243
|
+
for (const si of segIdxsRev) {
|
|
1186
1244
|
if (si < 0 || si >= pts.length - 1) continue;
|
|
1187
|
-
if (si === 0 || si === pts.length - 2)
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1245
|
+
if (si === 0 || si === pts.length - 2) {
|
|
1246
|
+
applyJogToTerminalSegment({
|
|
1247
|
+
pts,
|
|
1248
|
+
segmentIndex: si,
|
|
1249
|
+
offset,
|
|
1250
|
+
JOG_SIZE,
|
|
1251
|
+
EPS: EPS2
|
|
1252
|
+
});
|
|
1253
|
+
} else {
|
|
1254
|
+
const start = pts[si];
|
|
1255
|
+
const end = pts[si + 1];
|
|
1256
|
+
const isVertical = Math.abs(start.x - end.x) < EPS2;
|
|
1257
|
+
const isHorizontal = Math.abs(start.y - end.y) < EPS2;
|
|
1258
|
+
if (!isVertical && !isHorizontal) continue;
|
|
1259
|
+
if (isVertical) {
|
|
1195
1260
|
start.x += offset;
|
|
1196
|
-
appliedX.add(si);
|
|
1197
|
-
}
|
|
1198
|
-
if (!appliedX.has(si + 1)) {
|
|
1199
1261
|
end.x += offset;
|
|
1200
|
-
|
|
1201
|
-
}
|
|
1202
|
-
} else if (isHorizontal) {
|
|
1203
|
-
if (!appliedY.has(si)) {
|
|
1262
|
+
} else {
|
|
1204
1263
|
start.y += offset;
|
|
1205
|
-
appliedY.add(si);
|
|
1206
|
-
}
|
|
1207
|
-
if (!appliedY.has(si + 1)) {
|
|
1208
1264
|
end.y += offset;
|
|
1209
|
-
appliedY.add(si + 1);
|
|
1210
1265
|
}
|
|
1211
1266
|
}
|
|
1212
1267
|
}
|
|
@@ -1295,7 +1350,7 @@ var TraceOverlapShiftSolver = class extends BaseSolver {
|
|
|
1295
1350
|
return islands;
|
|
1296
1351
|
}
|
|
1297
1352
|
findNextOverlapIssue() {
|
|
1298
|
-
const EPS2 =
|
|
1353
|
+
const EPS2 = 2e-3;
|
|
1299
1354
|
const netIds = Object.keys(this.traceNetIslands);
|
|
1300
1355
|
for (let i = 0; i < netIds.length; i++) {
|
|
1301
1356
|
for (let j = i + 1; j < netIds.length; j++) {
|
package/lib/solvers/TraceOverlapShiftSolver/TraceOverlapIssueSolver/TraceOverlapIssueSolver.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { GraphicsObject } from "graphics-debug"
|
|
|
2
2
|
import { BaseSolver } from "lib/solvers/BaseSolver/BaseSolver"
|
|
3
3
|
import type { MspConnectionPairId } from "lib/solvers/MspConnectionPairSolver/MspConnectionPairSolver"
|
|
4
4
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
5
|
+
import { applyJogToTerminalSegment } from "./applyJogToTrace"
|
|
5
6
|
|
|
6
7
|
type ConnNetId = string
|
|
7
8
|
|
|
@@ -83,38 +84,39 @@ export class TraceOverlapIssueSolver extends BaseSolver {
|
|
|
83
84
|
|
|
84
85
|
const segIdxs = Array.from(segIdxSet).sort((a, b) => a - b)
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
const segIdxsRev = Array.from(segIdxSet)
|
|
88
|
+
.sort((a, b) => a - b)
|
|
89
|
+
.reverse()
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
if (si < 0 || si >= pts.length - 1) continue
|
|
92
|
-
// Do not move the first or last segment since they connect directly to pins
|
|
93
|
-
if (si === 0 || si === pts.length - 2) continue
|
|
94
|
-
const start = pts[si]!
|
|
95
|
-
const end = pts[si + 1]!
|
|
96
|
-
const isVertical = Math.abs(start.x - end.x) < EPS
|
|
97
|
-
const isHorizontal = Math.abs(start.y - end.y) < EPS
|
|
91
|
+
const JOG_SIZE = this.SHIFT_DISTANCE
|
|
98
92
|
|
|
99
|
-
|
|
93
|
+
// Process from end to start to keep indices valid after splicing
|
|
94
|
+
for (const si of segIdxsRev) {
|
|
95
|
+
if (si < 0 || si >= pts.length - 1) continue
|
|
100
96
|
|
|
101
|
-
if (
|
|
102
|
-
|
|
97
|
+
if (si === 0 || si === pts.length - 2) {
|
|
98
|
+
applyJogToTerminalSegment({
|
|
99
|
+
pts,
|
|
100
|
+
segmentIndex: si,
|
|
101
|
+
offset,
|
|
102
|
+
JOG_SIZE,
|
|
103
|
+
EPS,
|
|
104
|
+
})
|
|
105
|
+
} else {
|
|
106
|
+
// Internal segment - shift both points
|
|
107
|
+
const start = pts[si]!
|
|
108
|
+
const end = pts[si + 1]!
|
|
109
|
+
const isVertical = Math.abs(start.x - end.x) < EPS
|
|
110
|
+
const isHorizontal = Math.abs(start.y - end.y) < EPS
|
|
111
|
+
if (!isVertical && !isHorizontal) continue
|
|
112
|
+
|
|
113
|
+
if (isVertical) {
|
|
103
114
|
start.x += offset
|
|
104
|
-
appliedX.add(si)
|
|
105
|
-
}
|
|
106
|
-
if (!appliedX.has(si + 1)) {
|
|
107
115
|
end.x += offset
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
} else if (isHorizontal) {
|
|
111
|
-
if (!appliedY.has(si)) {
|
|
116
|
+
} else {
|
|
117
|
+
// Horizontal
|
|
112
118
|
start.y += offset
|
|
113
|
-
appliedY.add(si)
|
|
114
|
-
}
|
|
115
|
-
if (!appliedY.has(si + 1)) {
|
|
116
119
|
end.y += offset
|
|
117
|
-
appliedY.add(si + 1)
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
122
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Point } from "@tscircuit/math-utils"
|
|
2
|
+
|
|
3
|
+
export const applyJogToTerminalSegment = ({
|
|
4
|
+
pts,
|
|
5
|
+
segmentIndex: si,
|
|
6
|
+
offset,
|
|
7
|
+
JOG_SIZE,
|
|
8
|
+
EPS = 1e-6,
|
|
9
|
+
}: {
|
|
10
|
+
pts: Point[]
|
|
11
|
+
segmentIndex: number
|
|
12
|
+
offset: number
|
|
13
|
+
JOG_SIZE: number
|
|
14
|
+
EPS?: number
|
|
15
|
+
}) => {
|
|
16
|
+
if (si !== 0 && si !== pts.length - 2) return
|
|
17
|
+
|
|
18
|
+
const start = pts[si]!
|
|
19
|
+
const end = pts[si + 1]!
|
|
20
|
+
const isVertical = Math.abs(start.x - end.x) < EPS
|
|
21
|
+
const isHorizontal = Math.abs(start.y - end.y) < EPS
|
|
22
|
+
if (!isVertical && !isHorizontal) return
|
|
23
|
+
|
|
24
|
+
const segDir = isVertical
|
|
25
|
+
? end.y > start.y
|
|
26
|
+
? 1
|
|
27
|
+
: -1
|
|
28
|
+
: end.x > start.x
|
|
29
|
+
? 1
|
|
30
|
+
: -1
|
|
31
|
+
|
|
32
|
+
if (si === 0) {
|
|
33
|
+
if (isVertical) {
|
|
34
|
+
const jogY = start.y + segDir * JOG_SIZE
|
|
35
|
+
pts.splice(
|
|
36
|
+
1,
|
|
37
|
+
1,
|
|
38
|
+
{ x: start.x, y: jogY },
|
|
39
|
+
{ x: start.x + offset, y: jogY },
|
|
40
|
+
{ x: end.x + offset, y: end.y },
|
|
41
|
+
)
|
|
42
|
+
} else {
|
|
43
|
+
// Horizontal
|
|
44
|
+
const jogX = start.x + segDir * JOG_SIZE
|
|
45
|
+
pts.splice(
|
|
46
|
+
1,
|
|
47
|
+
1,
|
|
48
|
+
{ x: jogX, y: start.y },
|
|
49
|
+
{ x: jogX, y: start.y + offset },
|
|
50
|
+
{ x: end.x, y: end.y + offset },
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
// si === pts.length - 2
|
|
55
|
+
if (isVertical) {
|
|
56
|
+
const jogY = end.y - segDir * JOG_SIZE
|
|
57
|
+
pts.splice(
|
|
58
|
+
si,
|
|
59
|
+
1,
|
|
60
|
+
{ x: start.x + offset, y: start.y },
|
|
61
|
+
{ x: end.x + offset, y: jogY },
|
|
62
|
+
{ x: end.x, y: jogY },
|
|
63
|
+
)
|
|
64
|
+
} else {
|
|
65
|
+
// Horizontal
|
|
66
|
+
const jogX = end.x - segDir * JOG_SIZE
|
|
67
|
+
pts.splice(
|
|
68
|
+
si,
|
|
69
|
+
1,
|
|
70
|
+
{ x: start.x, y: start.y + offset },
|
|
71
|
+
{ x: jogX, y: end.y + offset },
|
|
72
|
+
{ x: jogX, y: end.y },
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -89,7 +89,7 @@ export class TraceOverlapShiftSolver extends BaseSolver {
|
|
|
89
89
|
overlappingTraceSegments: Array<OverlappingTraceSegmentLocator>
|
|
90
90
|
} | null {
|
|
91
91
|
// Detect the next set of overlapping segments between two different net islands.
|
|
92
|
-
const EPS =
|
|
92
|
+
const EPS = 2e-3
|
|
93
93
|
|
|
94
94
|
const netIds = Object.keys(this.traceNetIslands)
|
|
95
95
|
// Compare each pair of different nets
|
package/package.json
CHANGED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { GenericSolverDebugger } from "site/components/GenericSolverDebugger"
|
|
2
|
+
import { useMemo } from "react"
|
|
3
|
+
import type { InputProblem } from "lib/types/InputProblem"
|
|
4
|
+
import { SchematicTracePipelineSolver } from "lib/index"
|
|
5
|
+
|
|
6
|
+
const inputProblem = {
|
|
7
|
+
chips: [
|
|
8
|
+
{
|
|
9
|
+
chipId: "schematic_component_0",
|
|
10
|
+
center: {
|
|
11
|
+
x: 0,
|
|
12
|
+
y: 0,
|
|
13
|
+
},
|
|
14
|
+
width: 0.4,
|
|
15
|
+
height: 0.8,
|
|
16
|
+
pins: [
|
|
17
|
+
{
|
|
18
|
+
pinId: "U1.6",
|
|
19
|
+
x: 0.6000000000000001,
|
|
20
|
+
y: -0.2,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
pinId: "U1.8",
|
|
24
|
+
x: 0.6000000000000001,
|
|
25
|
+
y: 0,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
pinId: "U1.1",
|
|
29
|
+
x: 0.6000000000000001,
|
|
30
|
+
y: 0.2,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
chipId: "schematic_component_1",
|
|
36
|
+
center: {
|
|
37
|
+
x: 1.4,
|
|
38
|
+
y: 0.55,
|
|
39
|
+
},
|
|
40
|
+
width: 0.5291665999999999,
|
|
41
|
+
height: 1.0583333000000001,
|
|
42
|
+
pins: [
|
|
43
|
+
{
|
|
44
|
+
pinId: "C2.1",
|
|
45
|
+
x: 1.4002733499999995,
|
|
46
|
+
y: -0.0012093000000001908,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
pinId: "C2.2",
|
|
50
|
+
x: 1.3997266500000003,
|
|
51
|
+
y: 1.1012093000000003,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
chipId: "schematic_component_2",
|
|
57
|
+
center: {
|
|
58
|
+
x: 2.7,
|
|
59
|
+
y: 1.3,
|
|
60
|
+
},
|
|
61
|
+
width: 1.0583332999999997,
|
|
62
|
+
height: 0.388910699999999,
|
|
63
|
+
pins: [
|
|
64
|
+
{
|
|
65
|
+
pinId: "R1.1",
|
|
66
|
+
x: 2.1487093,
|
|
67
|
+
y: 1.3002732499999994,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
pinId: "R1.2",
|
|
71
|
+
x: 3.2512907000000006,
|
|
72
|
+
y: 1.2997267500000007,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
chipId: "schematic_component_3",
|
|
78
|
+
center: {
|
|
79
|
+
x: 4.4,
|
|
80
|
+
y: 0,
|
|
81
|
+
},
|
|
82
|
+
width: 0.4,
|
|
83
|
+
height: 0.4,
|
|
84
|
+
pins: [
|
|
85
|
+
{
|
|
86
|
+
pinId: "JP5.1",
|
|
87
|
+
x: 3.8000000000000003,
|
|
88
|
+
y: 0,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
chipId: "schematic_component_4",
|
|
94
|
+
center: {
|
|
95
|
+
x: 4.4,
|
|
96
|
+
y: -0.9,
|
|
97
|
+
},
|
|
98
|
+
width: 0.4,
|
|
99
|
+
height: 0.4,
|
|
100
|
+
pins: [
|
|
101
|
+
{
|
|
102
|
+
pinId: "JP9.1",
|
|
103
|
+
x: 3.8000000000000003,
|
|
104
|
+
y: -0.9,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
chipId: "schematic_component_5",
|
|
110
|
+
center: {
|
|
111
|
+
x: 2,
|
|
112
|
+
y: -1.1,
|
|
113
|
+
},
|
|
114
|
+
width: 0.8843008999999997,
|
|
115
|
+
height: 0.5299361999999987,
|
|
116
|
+
pins: [
|
|
117
|
+
{
|
|
118
|
+
pinId: "JP8.1",
|
|
119
|
+
x: 2.4458007999999998,
|
|
120
|
+
y: -1.2015872704999997,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
pinId: "JP8.2",
|
|
124
|
+
x: 2.0034928,
|
|
125
|
+
y: -0.8474009705000005,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
pinId: "JP8.3",
|
|
129
|
+
x: 1.5541992,
|
|
130
|
+
y: -1.2014628704999997,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
directConnections: [
|
|
136
|
+
{
|
|
137
|
+
pinIds: ["C2.1", "U1.8"],
|
|
138
|
+
netId: "capacitor.C2 > port.pin1 to .U1 > .pin8",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
pinIds: ["C2.2", "R1.1"],
|
|
142
|
+
netId: "capacitor.C2 > port.pin2 to .R1 > .pin1",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
pinIds: ["R1.1", "U1.1"],
|
|
146
|
+
netId: "resistor.R1 > port.pin1 to .U1 > .pin1",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
pinIds: ["JP5.1", "R1.2"],
|
|
150
|
+
netId: "pinheader.JP5 > port.pin1 to .R1 > .pin2",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
pinIds: ["JP9.1", "R1.2"],
|
|
154
|
+
netId: "pinheader.JP9 > port.pin1 to .R1 > .pin2",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
pinIds: ["JP8.2", "U1.6"],
|
|
158
|
+
netId: "solderjumper.JP8 > port.pin2 to .U1 > .pin6",
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
netConnections: [
|
|
162
|
+
{
|
|
163
|
+
netId: "PAD",
|
|
164
|
+
pinIds: ["R1.2", "JP5.1", "JP9.1"],
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
availableNetLabelOrientations: {},
|
|
168
|
+
maxMspPairDistance: 5,
|
|
169
|
+
} as InputProblem
|
|
170
|
+
|
|
171
|
+
export default () => {
|
|
172
|
+
const solver = useMemo(
|
|
173
|
+
() => new SchematicTracePipelineSolver(inputProblem),
|
|
174
|
+
[],
|
|
175
|
+
)
|
|
176
|
+
return <GenericSolverDebugger solver={solver} />
|
|
177
|
+
}
|
|
@@ -70,7 +70,7 @@ x+" data-x="1.48" data-y="-0.665" cx="516.9811320754716" cy="426.7924528301886"
|
|
|
70
70
|
<polyline data-points="0.5800000000000001,-0.665 0.1,-0.665 0.1,0.1 -1.6800000000000002,0.1 -1.6800000000000002,0.765 -1.58,0.765" data-type="line" data-label="" points="381.1320754716981,426.7924528301886 308.6792452830188,426.7924528301886 308.6792452830188,311.3207547169811 39.99999999999997,311.3207547169811 39.99999999999997,210.94339622641508 55.09433962264151,210.94339622641508" fill="none" stroke="purple" stroke-width="1" />
|
|
71
71
|
</g>
|
|
72
72
|
<g>
|
|
73
|
-
<polyline data-points="1.48,-0.665 1.78,-0.665 1.78,0.03527232500000027 0,0.03527232500000027 0,0.765 -0.48,0.765" data-type="line" data-label="" points="516.9811320754716,426.7924528301886 562.2641509433961,426.7924528301886 562.2641509433961,321.0909698113207 293.58490566037733,321.0909698113207 293.58490566037733,210.94339622641508 221.1320754716981,210.94339622641508" fill="none" stroke="purple" stroke-width="1" />
|
|
73
|
+
<polyline data-points="1.48,-0.665 1.78,-0.665 1.78,0.03527232500000027 0,0.03527232500000027 0,0.865 -0.38,0.865 -0.38,0.765 -0.48,0.765" data-type="line" data-label="" points="516.9811320754716,426.7924528301886 562.2641509433961,426.7924528301886 562.2641509433961,321.0909698113207 293.58490566037733,321.0909698113207 293.58490566037733,195.84905660377356 236.2264150943396,195.84905660377356 236.2264150943396,210.94339622641508 221.1320754716981,210.94339622641508" fill="none" stroke="purple" stroke-width="1" />
|
|
74
74
|
</g>
|
|
75
75
|
<g>
|
|
76
76
|
<rect data-type="rect" data-label="schematic_component_0" data-x="-1.03" data-y="0.765" x="55.09433962264151" y="181.59164528301895" width="166.0377358490566" height="58.70350188679228" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.006625000000000001" />
|
|
@@ -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="U1.6
|
|
5
|
+
x+" data-x="0.6000000000000001" data-y="-0.2" cx="160.00000000000003" cy="359.23793250000006" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
|
|
6
|
+
</g>
|
|
7
|
+
<g>
|
|
8
|
+
<circle data-type="point" data-label="U1.8
|
|
9
|
+
x+" data-x="0.6000000000000001" data-y="0" cx="160.00000000000003" cy="339.23793250000006" r="3" fill="hsl(326, 100%, 50%, 0.8)" />
|
|
10
|
+
</g>
|
|
11
|
+
<g>
|
|
12
|
+
<circle data-type="point" data-label="U1.1
|
|
13
|
+
x+" data-x="0.6000000000000001" data-y="0.2" cx="160.00000000000003" cy="319.23793250000006" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
|
|
14
|
+
</g>
|
|
15
|
+
<g>
|
|
16
|
+
<circle data-type="point" data-label="C2.1
|
|
17
|
+
y-" data-x="1.4002733499999995" data-y="-0.0012093000000001908" cx="240.027335" cy="339.3588625000001" r="3" fill="hsl(2, 100%, 50%, 0.8)" />
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
<circle data-type="point" data-label="C2.2
|
|
21
|
+
y+" data-x="1.3997266500000003" data-y="1.1012093000000003" cx="239.97266500000006" cy="229.1170025" r="3" fill="hsl(3, 100%, 50%, 0.8)" />
|
|
22
|
+
</g>
|
|
23
|
+
<g>
|
|
24
|
+
<circle data-type="point" data-label="R1.1
|
|
25
|
+
x-" data-x="2.1487092999999997" data-y="1.3002732499999994" cx="314.87093" cy="209.21060750000012" r="3" fill="hsl(226, 100%, 50%, 0.8)" />
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
<circle data-type="point" data-label="R1.2
|
|
29
|
+
x+" data-x="3.2512907000000006" data-y="1.2997267500000007" cx="425.12907000000007" cy="209.2652575" r="3" fill="hsl(227, 100%, 50%, 0.8)" />
|
|
30
|
+
</g>
|
|
31
|
+
<g>
|
|
32
|
+
<circle data-type="point" data-label="JP5.1
|
|
33
|
+
x-" data-x="3.8000000000000003" data-y="0" cx="480" cy="339.23793250000006" r="3" fill="hsl(242, 100%, 50%, 0.8)" />
|
|
34
|
+
</g>
|
|
35
|
+
<g>
|
|
36
|
+
<circle data-type="point" data-label="JP9.1
|
|
37
|
+
x-" data-x="3.8000000000000003" data-y="-0.9" cx="480" cy="429.23793250000006" r="3" fill="hsl(126, 100%, 50%, 0.8)" />
|
|
38
|
+
</g>
|
|
39
|
+
<g>
|
|
40
|
+
<circle data-type="point" data-label="JP8.1
|
|
41
|
+
x+" data-x="2.4458007999999998" data-y="-1.2015872704999997" cx="344.58008" cy="459.39665955000004" r="3" fill="hsl(245, 100%, 50%, 0.8)" />
|
|
42
|
+
</g>
|
|
43
|
+
<g>
|
|
44
|
+
<circle data-type="point" data-label="JP8.2
|
|
45
|
+
y+" data-x="2.0034928" data-y="-0.8350319000000007" cx="300.34928" cy="422.74112250000013" r="3" fill="hsl(246, 100%, 50%, 0.8)" />
|
|
46
|
+
</g>
|
|
47
|
+
<g>
|
|
48
|
+
<circle data-type="point" data-label="JP8.3
|
|
49
|
+
x-" data-x="1.5541992" data-y="-1.2014628704999997" cx="255.41992000000002" cy="459.38421955" r="3" fill="hsl(247, 100%, 50%, 0.8)" />
|
|
50
|
+
</g>
|
|
51
|
+
<g>
|
|
52
|
+
<circle data-type="point" data-label="" data-x="1.4002733499999995" data-y="-0.30120930000000024" cx="240.027335" cy="369.3588625000001" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
53
|
+
</g>
|
|
54
|
+
<g>
|
|
55
|
+
<circle data-type="point" data-label="" data-x="0.733854175" data-y="0.2" cx="173.38541750000002" cy="319.23793250000006" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
56
|
+
</g>
|
|
57
|
+
<g>
|
|
58
|
+
<circle data-type="point" data-label="" data-x="3.451290700000001" data-y="1.2997267500000007" cx="445.12907000000007" cy="209.2652575" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
59
|
+
</g>
|
|
60
|
+
<g>
|
|
61
|
+
<circle data-type="point" data-label="" data-x="2.0034928" data-y="-0.46751595000000035" cx="300.34928" cy="385.9895275000001" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
62
|
+
</g>
|
|
63
|
+
<g>
|
|
64
|
+
<polyline data-points="1.4002733499999995,-0.0012093000000001908 0.6000000000000001,0" data-type="line" data-label="" points="240.027335,339.3588625000001 160.00000000000003,339.23793250000006" fill="none" stroke="hsl(256, 100%, 50%, 0.8)" stroke-width="1" />
|
|
65
|
+
</g>
|
|
66
|
+
<g>
|
|
67
|
+
<polyline data-points="1.3997266500000003,1.1012093000000003 2.1487092999999997,1.3002732499999994" data-type="line" data-label="" points="239.97266500000006,229.1170025 314.87093,209.21060750000012" fill="none" stroke="hsl(256, 100%, 50%, 0.8)" stroke-width="1" />
|
|
68
|
+
</g>
|
|
69
|
+
<g>
|
|
70
|
+
<polyline data-points="2.1487092999999997,1.3002732499999994 0.6000000000000001,0.2" data-type="line" data-label="" points="314.87093,209.21060750000012 160.00000000000003,319.23793250000006" fill="none" stroke="hsl(280, 100%, 50%, 0.8)" stroke-width="1" />
|
|
71
|
+
</g>
|
|
72
|
+
<g>
|
|
73
|
+
<polyline data-points="3.8000000000000003,0 3.2512907000000006,1.2997267500000007" data-type="line" data-label="" points="480,339.23793250000006 425.12907000000007,209.2652575" fill="none" stroke="hsl(336, 100%, 50%, 0.8)" stroke-width="1" />
|
|
74
|
+
</g>
|
|
75
|
+
<g>
|
|
76
|
+
<polyline data-points="3.8000000000000003,-0.9 3.2512907000000006,1.2997267500000007" data-type="line" data-label="" points="480,429.23793250000006 425.12907000000007,209.2652575" fill="none" stroke="hsl(336, 100%, 50%, 0.8)" stroke-width="1" />
|
|
77
|
+
</g>
|
|
78
|
+
<g>
|
|
79
|
+
<polyline data-points="2.0034928,-0.8350319000000007 0.6000000000000001,-0.2" data-type="line" data-label="" points="300.34928,422.74112250000013 160.00000000000003,359.23793250000006" fill="none" stroke="hsl(352, 100%, 50%, 0.8)" stroke-width="1" />
|
|
80
|
+
</g>
|
|
81
|
+
<g>
|
|
82
|
+
<polyline data-points="3.2512907000000006,1.2997267500000007 3.8000000000000003,0" data-type="line" data-label="" points="425.12907000000007,209.2652575 480,339.23793250000006" fill="none" stroke="hsl(123, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
83
|
+
</g>
|
|
84
|
+
<g>
|
|
85
|
+
<polyline data-points="3.2512907000000006,1.2997267500000007 3.8000000000000003,-0.9" data-type="line" data-label="" points="425.12907000000007,209.2652575 480,429.23793250000006" fill="none" stroke="hsl(123, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
86
|
+
</g>
|
|
87
|
+
<g>
|
|
88
|
+
<polyline data-points="3.8000000000000003,0 3.8000000000000003,-0.9" data-type="line" data-label="" points="480,339.23793250000006 480,429.23793250000006" fill="none" stroke="hsl(123, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
89
|
+
</g>
|
|
90
|
+
<g>
|
|
91
|
+
<polyline data-points="1.4002733499999995,-0.0012093000000001908 1.4002733499999995,-0.30120930000000024 1.0001366749999998,-0.30120930000000024 1.0001366749999998,0 0.6000000000000001,0" data-type="line" data-label="" points="240.027335,339.3588625000001 240.027335,369.3588625000001 200.0136675,369.3588625000001 200.0136675,339.23793250000006 160.00000000000003,339.23793250000006" fill="none" stroke="purple" stroke-width="1" />
|
|
92
|
+
</g>
|
|
93
|
+
<g>
|
|
94
|
+
<polyline data-points="2.1487092999999997,1.3002732499999994 1.3997266500000003,1.3002732499999994 1.3997266500000003,1.1012093000000003" data-type="line" data-label="" points="314.87093,209.21060750000012 239.97266500000006,209.21060750000012 239.97266500000006,229.1170025" fill="none" stroke="purple" stroke-width="1" />
|
|
95
|
+
</g>
|
|
96
|
+
<g>
|
|
97
|
+
<polyline data-points="0.6000000000000001,0.2 0.86770835,0.2 0.86770835,1.1033769750000004 1.3997266500000003,1.1033769750000004 1.3997266500000003,1.1012093000000003" data-type="line" data-label="" points="160.00000000000003,319.23793250000006 186.77083500000003,319.23793250000006 186.77083500000003,228.900235 239.97266500000006,228.900235 239.97266500000006,229.1170025" fill="none" stroke="purple" stroke-width="1" />
|
|
98
|
+
</g>
|
|
99
|
+
<g>
|
|
100
|
+
<polyline data-points="3.8000000000000003,-0.9 3.6000000000000005,-0.9 3.6000000000000005,0 3.8000000000000003,0" data-type="line" data-label="" points="480,429.23793250000006 460.0000000000001,429.23793250000006 460.0000000000001,339.23793250000006 480,339.23793250000006" fill="none" stroke="purple" stroke-width="1" />
|
|
101
|
+
</g>
|
|
102
|
+
<g>
|
|
103
|
+
<polyline data-points="3.2512907000000006,1.2997267500000007 3.451290700000001,1.2997267500000007 3.5256453500000005,1.2997267500000007 3.5256453500000005,0 3.6,0 3.8000000000000003,0" data-type="line" data-label="" points="425.12907000000007,209.2652575 445.12907000000007,209.2652575 452.5645350000001,209.2652575 452.5645350000001,339.23793250000006 460,339.23793250000006 480,339.23793250000006" fill="none" stroke="purple" stroke-width="1" />
|
|
104
|
+
</g>
|
|
105
|
+
<g>
|
|
106
|
+
<polyline data-points="2.0034928,-0.8350319000000007 2.0034928,-0.1 0.7000000000000001,-0.1 0.7000000000000001,-0.2 0.6000000000000001,-0.2" data-type="line" data-label="" points="300.34928,422.74112250000013 300.34928,349.23793250000006 170.00000000000003,349.23793250000006 170.00000000000003,359.23793250000006 160.00000000000003,359.23793250000006" fill="none" stroke="purple" stroke-width="1" />
|
|
107
|
+
</g>
|
|
108
|
+
<g>
|
|
109
|
+
<rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="40.00000000000002" y="299.23793250000006" width="120" height="80" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01" />
|
|
110
|
+
</g>
|
|
111
|
+
<g>
|
|
112
|
+
<rect data-type="rect" data-label="schematic_component_1" data-x="1.4" data-y="0.55" x="213.54167" y="229.1170025" width="52.916660000000036" height="110.24186000000009" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01" />
|
|
113
|
+
</g>
|
|
114
|
+
<g>
|
|
115
|
+
<rect data-type="rect" data-label="schematic_component_2" data-x="2.7" data-y="1.3" x="314.87093" y="189.7923975000001" width="110.25814000000008" height="38.8910699999999" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01" />
|
|
116
|
+
</g>
|
|
117
|
+
<g>
|
|
118
|
+
<rect data-type="rect" data-label="schematic_component_3" data-x="4.4" data-y="0" x="480" y="319.23793250000006" width="120" height="40" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01" />
|
|
119
|
+
</g>
|
|
120
|
+
<g>
|
|
121
|
+
<rect data-type="rect" data-label="schematic_component_4" data-x="4.4" data-y="-0.9" x="480" y="409.23793250000006" width="120" height="40" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01" />
|
|
122
|
+
</g>
|
|
123
|
+
<g>
|
|
124
|
+
<rect data-type="rect" data-label="schematic_component_5" data-x="2" data-y="-1.1" x="255.41992000000002" y="422.74112250000013" width="89.16015999999999" height="52.99361999999991" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.01" />
|
|
125
|
+
</g>
|
|
126
|
+
<g>
|
|
127
|
+
<rect data-type="rect" data-label="" data-x="1.6252733499999996" data-y="-0.30120930000000024" x="240.027335" y="359.3588625000001" width="45" height="20" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.01" />
|
|
128
|
+
</g>
|
|
129
|
+
<g>
|
|
130
|
+
<rect data-type="rect" data-label="" data-x="0.733854175" data-y="0.42500000000000004" x="163.38541750000005" y="274.23793250000006" width="19.99999999999997" height="45" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.01" />
|
|
131
|
+
</g>
|
|
132
|
+
<g>
|
|
133
|
+
<rect data-type="rect" data-label="" data-x="3.451290700000001" data-y="1.5247267500000008" x="435.12907000000007" y="164.26525749999996" width="20" height="45.00000000000003" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.01" />
|
|
134
|
+
</g>
|
|
135
|
+
<g>
|
|
136
|
+
<rect data-type="rect" data-label="" data-x="2.2284928" data-y="-0.46751595000000035" x="300.34928" y="375.9895275000001" width="45" height="19.999999999999943" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.01" />
|
|
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": 100,
|
|
167
|
+
"c": 0,
|
|
168
|
+
"e": 100.00000000000003,
|
|
169
|
+
"b": 0,
|
|
170
|
+
"d": -100,
|
|
171
|
+
"f": 339.23793250000006
|
|
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,175 @@
|
|
|
1
|
+
import { expect } from "bun:test"
|
|
2
|
+
import { test } from "bun:test"
|
|
3
|
+
import { SchematicTracePipelineSolver, type InputProblem } from "lib/index"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
|
|
6
|
+
const inputProblem = {
|
|
7
|
+
chips: [
|
|
8
|
+
{
|
|
9
|
+
chipId: "schematic_component_0",
|
|
10
|
+
center: {
|
|
11
|
+
x: 0,
|
|
12
|
+
y: 0,
|
|
13
|
+
},
|
|
14
|
+
width: 0.4,
|
|
15
|
+
height: 0.8,
|
|
16
|
+
pins: [
|
|
17
|
+
{
|
|
18
|
+
pinId: "U1.6",
|
|
19
|
+
x: 0.6000000000000001,
|
|
20
|
+
y: -0.2,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
pinId: "U1.8",
|
|
24
|
+
x: 0.6000000000000001,
|
|
25
|
+
y: 0,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
pinId: "U1.1",
|
|
29
|
+
x: 0.6000000000000001,
|
|
30
|
+
y: 0.2,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
chipId: "schematic_component_1",
|
|
36
|
+
center: {
|
|
37
|
+
x: 1.4,
|
|
38
|
+
y: 0.55,
|
|
39
|
+
},
|
|
40
|
+
width: 0.5291665999999999,
|
|
41
|
+
height: 1.0583333000000001,
|
|
42
|
+
pins: [
|
|
43
|
+
{
|
|
44
|
+
pinId: "C2.1",
|
|
45
|
+
x: 1.4002733499999995,
|
|
46
|
+
y: -0.0012093000000001908,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
pinId: "C2.2",
|
|
50
|
+
x: 1.3997266500000003,
|
|
51
|
+
y: 1.1012093000000003,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
chipId: "schematic_component_2",
|
|
57
|
+
center: {
|
|
58
|
+
x: 2.7,
|
|
59
|
+
y: 1.3,
|
|
60
|
+
},
|
|
61
|
+
width: 1.0583332999999997,
|
|
62
|
+
height: 0.388910699999999,
|
|
63
|
+
pins: [
|
|
64
|
+
{
|
|
65
|
+
pinId: "R1.1",
|
|
66
|
+
x: 2.1487093,
|
|
67
|
+
y: 1.3002732499999994,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
pinId: "R1.2",
|
|
71
|
+
x: 3.2512907000000006,
|
|
72
|
+
y: 1.2997267500000007,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
chipId: "schematic_component_3",
|
|
78
|
+
center: {
|
|
79
|
+
x: 4.4,
|
|
80
|
+
y: 0,
|
|
81
|
+
},
|
|
82
|
+
width: 0.4,
|
|
83
|
+
height: 0.4,
|
|
84
|
+
pins: [
|
|
85
|
+
{
|
|
86
|
+
pinId: "JP5.1",
|
|
87
|
+
x: 3.8000000000000003,
|
|
88
|
+
y: 0,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
chipId: "schematic_component_4",
|
|
94
|
+
center: {
|
|
95
|
+
x: 4.4,
|
|
96
|
+
y: -0.9,
|
|
97
|
+
},
|
|
98
|
+
width: 0.4,
|
|
99
|
+
height: 0.4,
|
|
100
|
+
pins: [
|
|
101
|
+
{
|
|
102
|
+
pinId: "JP9.1",
|
|
103
|
+
x: 3.8000000000000003,
|
|
104
|
+
y: -0.9,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
chipId: "schematic_component_5",
|
|
110
|
+
center: {
|
|
111
|
+
x: 2,
|
|
112
|
+
y: -1.1,
|
|
113
|
+
},
|
|
114
|
+
width: 0.8843008999999997,
|
|
115
|
+
height: 0.5299361999999987,
|
|
116
|
+
pins: [
|
|
117
|
+
{
|
|
118
|
+
pinId: "JP8.1",
|
|
119
|
+
x: 2.4458007999999998,
|
|
120
|
+
y: -1.2015872704999997,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
pinId: "JP8.2",
|
|
124
|
+
x: 2.0034928,
|
|
125
|
+
y: -0.8474009705000005,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
pinId: "JP8.3",
|
|
129
|
+
x: 1.5541992,
|
|
130
|
+
y: -1.2014628704999997,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
directConnections: [
|
|
136
|
+
{
|
|
137
|
+
pinIds: ["C2.1", "U1.8"],
|
|
138
|
+
netId: "capacitor.C2 > port.pin1 to .U1 > .pin8",
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
pinIds: ["C2.2", "R1.1"],
|
|
142
|
+
netId: "capacitor.C2 > port.pin2 to .R1 > .pin1",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
pinIds: ["R1.1", "U1.1"],
|
|
146
|
+
netId: "resistor.R1 > port.pin1 to .U1 > .pin1",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
pinIds: ["JP5.1", "R1.2"],
|
|
150
|
+
netId: "pinheader.JP5 > port.pin1 to .R1 > .pin2",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
pinIds: ["JP9.1", "R1.2"],
|
|
154
|
+
netId: "pinheader.JP9 > port.pin1 to .R1 > .pin2",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
pinIds: ["JP8.2", "U1.6"],
|
|
158
|
+
netId: "solderjumper.JP8 > port.pin2 to .U1 > .pin6",
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
netConnections: [
|
|
162
|
+
{
|
|
163
|
+
netId: "PAD",
|
|
164
|
+
pinIds: ["R1.2", "JP5.1", "JP9.1"],
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
availableNetLabelOrientations: {},
|
|
168
|
+
maxMspPairDistance: 5,
|
|
169
|
+
} as InputProblem
|
|
170
|
+
|
|
171
|
+
test("example16", () => {
|
|
172
|
+
const solver = new SchematicTracePipelineSolver(inputProblem)
|
|
173
|
+
solver.solve()
|
|
174
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
175
|
+
})
|