@tscircuit/schematic-trace-solver 0.0.35 → 0.0.37
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.d.ts +3 -0
- package/dist/index.js +46 -14
- package/lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver.ts +13 -0
- package/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/SingleNetLabelPlacementSolver.ts +11 -1
- package/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/geometry.ts +13 -3
- package/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/solvePortOnlyPin.ts +10 -2
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +15 -3
- package/lib/types/InputProblem.ts +1 -0
- package/package.json +1 -1
- package/site/examples/example21.page.tsx +177 -0
- package/tests/examples/__snapshots__/example20.snap.svg +235 -0
- package/tests/examples/__snapshots__/example21.snap.svg +272 -0
- package/tests/examples/example20.test.tsx +190 -0
- package/tests/examples/example21.test.tsx +183 -0
package/dist/index.d.ts
CHANGED
|
@@ -79,6 +79,7 @@ interface InputDirectConnection {
|
|
|
79
79
|
interface InputNetConnection {
|
|
80
80
|
netId: string;
|
|
81
81
|
pinIds: Array<PinId>;
|
|
82
|
+
netLabelWidth?: number;
|
|
82
83
|
}
|
|
83
84
|
interface InputProblem {
|
|
84
85
|
chips: Array<InputChip>;
|
|
@@ -279,6 +280,7 @@ declare class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
279
280
|
overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup;
|
|
280
281
|
availableOrientations: Array<FacingDirection>;
|
|
281
282
|
chipObstacleSpatialIndex: ChipObstacleSpatialIndex;
|
|
283
|
+
netLabelWidth?: number;
|
|
282
284
|
netLabelPlacement: NetLabelPlacement | null;
|
|
283
285
|
testedCandidates: Array<{
|
|
284
286
|
center: {
|
|
@@ -306,6 +308,7 @@ declare class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
306
308
|
inputTraceMap: Record<MspConnectionPairId, SolvedTracePath>;
|
|
307
309
|
overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup;
|
|
308
310
|
availableOrientations: FacingDirection[];
|
|
311
|
+
netLabelWidth?: number;
|
|
309
312
|
});
|
|
310
313
|
getConstructorParams(): ConstructorParameters<typeof SingleNetLabelPlacementSolver>[0];
|
|
311
314
|
_step(): void;
|
package/dist/index.js
CHANGED
|
@@ -776,10 +776,17 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
776
776
|
return;
|
|
777
777
|
}
|
|
778
778
|
const { path, collisionChipIds } = state;
|
|
779
|
+
const [PA, PB] = this.pins;
|
|
779
780
|
const collision = findFirstCollision(path, this.obstacles);
|
|
780
781
|
if (!collision) {
|
|
781
|
-
|
|
782
|
-
|
|
782
|
+
const first = path[0];
|
|
783
|
+
const last = path[path.length - 1];
|
|
784
|
+
const EPS4 = 1e-9;
|
|
785
|
+
const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS4 && Math.abs(p.y - q.y) < EPS4;
|
|
786
|
+
if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
|
|
787
|
+
this.solvedTracePath = path;
|
|
788
|
+
this.solved = true;
|
|
789
|
+
}
|
|
783
790
|
return;
|
|
784
791
|
}
|
|
785
792
|
let { segIndex, rect } = collision;
|
|
@@ -802,7 +809,6 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
802
809
|
if (!axis) {
|
|
803
810
|
return;
|
|
804
811
|
}
|
|
805
|
-
const [PA, PB] = this.pins;
|
|
806
812
|
const candidates = [];
|
|
807
813
|
if (collisionChipIds.size === 0) {
|
|
808
814
|
const m1 = midBetweenPointAndRect(axis, { x: PA.x, y: PA.y }, rect);
|
|
@@ -1371,15 +1377,18 @@ var ChipObstacleSpatialIndex = class {
|
|
|
1371
1377
|
// lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/geometry.ts
|
|
1372
1378
|
var NET_LABEL_HORIZONTAL_WIDTH = 0.45;
|
|
1373
1379
|
var NET_LABEL_HORIZONTAL_HEIGHT = 0.2;
|
|
1374
|
-
function getDimsForOrientation(
|
|
1380
|
+
function getDimsForOrientation(params) {
|
|
1381
|
+
const { orientation, netLabelWidth } = params;
|
|
1382
|
+
const horizWidth = typeof netLabelWidth === "number" ? netLabelWidth : NET_LABEL_HORIZONTAL_WIDTH;
|
|
1375
1383
|
if (orientation === "y+" || orientation === "y-") {
|
|
1376
1384
|
return {
|
|
1385
|
+
// Rotated, so width/height swap
|
|
1377
1386
|
width: NET_LABEL_HORIZONTAL_HEIGHT,
|
|
1378
|
-
height:
|
|
1387
|
+
height: horizWidth
|
|
1379
1388
|
};
|
|
1380
1389
|
}
|
|
1381
1390
|
return {
|
|
1382
|
-
width:
|
|
1391
|
+
width: horizWidth,
|
|
1383
1392
|
height: NET_LABEL_HORIZONTAL_HEIGHT
|
|
1384
1393
|
};
|
|
1385
1394
|
}
|
|
@@ -1508,7 +1517,8 @@ function solveNetLabelPlacementForPortOnlyPin(params) {
|
|
|
1508
1517
|
inputTraceMap,
|
|
1509
1518
|
chipObstacleSpatialIndex,
|
|
1510
1519
|
overlappingSameNetTraceGroup,
|
|
1511
|
-
availableOrientations
|
|
1520
|
+
availableOrientations,
|
|
1521
|
+
netLabelWidth
|
|
1512
1522
|
} = params;
|
|
1513
1523
|
const pinId = overlappingSameNetTraceGroup.portOnlyPinId;
|
|
1514
1524
|
if (!pinId) {
|
|
@@ -1540,7 +1550,10 @@ function solveNetLabelPlacementForPortOnlyPin(params) {
|
|
|
1540
1550
|
const outwardOf = (o) => o === "x+" ? { x: 1, y: 0 } : o === "x-" ? { x: -1, y: 0 } : o === "y+" ? { x: 0, y: 1 } : { x: 0, y: -1 };
|
|
1541
1551
|
const testedCandidates = [];
|
|
1542
1552
|
for (const orientation of orientations) {
|
|
1543
|
-
const { width: width2, height: height2 } = getDimsForOrientation(
|
|
1553
|
+
const { width: width2, height: height2 } = getDimsForOrientation({
|
|
1554
|
+
orientation,
|
|
1555
|
+
netLabelWidth
|
|
1556
|
+
});
|
|
1544
1557
|
const baseCenter2 = getCenterFromAnchor(anchor, orientation, width2, height2);
|
|
1545
1558
|
const outward2 = outwardOf(orientation);
|
|
1546
1559
|
const offset2 = 1e-3;
|
|
@@ -1607,7 +1620,10 @@ function solveNetLabelPlacementForPortOnlyPin(params) {
|
|
|
1607
1620
|
return { placement, testedCandidates };
|
|
1608
1621
|
}
|
|
1609
1622
|
const fallbackOrientation = pinFacingDirection;
|
|
1610
|
-
const { width, height } = getDimsForOrientation(
|
|
1623
|
+
const { width, height } = getDimsForOrientation({
|
|
1624
|
+
orientation: fallbackOrientation,
|
|
1625
|
+
netLabelWidth
|
|
1626
|
+
});
|
|
1611
1627
|
const baseCenter = getCenterFromAnchor(
|
|
1612
1628
|
anchor,
|
|
1613
1629
|
fallbackOrientation,
|
|
@@ -1699,6 +1715,8 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
1699
1715
|
overlappingSameNetTraceGroup;
|
|
1700
1716
|
availableOrientations;
|
|
1701
1717
|
chipObstacleSpatialIndex;
|
|
1718
|
+
// Optional override for the width of the net label (per netId)
|
|
1719
|
+
netLabelWidth;
|
|
1702
1720
|
netLabelPlacement = null;
|
|
1703
1721
|
testedCandidates = [];
|
|
1704
1722
|
constructor(params) {
|
|
@@ -1707,6 +1725,7 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
1707
1725
|
this.inputTraceMap = params.inputTraceMap;
|
|
1708
1726
|
this.overlappingSameNetTraceGroup = params.overlappingSameNetTraceGroup;
|
|
1709
1727
|
this.availableOrientations = params.availableOrientations;
|
|
1728
|
+
this.netLabelWidth = params.netLabelWidth;
|
|
1710
1729
|
this.chipObstacleSpatialIndex = params.inputProblem._chipObstacleSpatialIndex ?? new ChipObstacleSpatialIndex(params.inputProblem.chips);
|
|
1711
1730
|
}
|
|
1712
1731
|
getConstructorParams() {
|
|
@@ -1714,7 +1733,8 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
1714
1733
|
inputProblem: this.inputProblem,
|
|
1715
1734
|
inputTraceMap: this.inputTraceMap,
|
|
1716
1735
|
overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
|
|
1717
|
-
availableOrientations: this.availableOrientations
|
|
1736
|
+
availableOrientations: this.availableOrientations,
|
|
1737
|
+
netLabelWidth: this.netLabelWidth
|
|
1718
1738
|
};
|
|
1719
1739
|
}
|
|
1720
1740
|
_step() {
|
|
@@ -1728,7 +1748,8 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
1728
1748
|
inputTraceMap: this.inputTraceMap,
|
|
1729
1749
|
chipObstacleSpatialIndex: this.chipObstacleSpatialIndex,
|
|
1730
1750
|
overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
|
|
1731
|
-
availableOrientations: this.availableOrientations
|
|
1751
|
+
availableOrientations: this.availableOrientations,
|
|
1752
|
+
netLabelWidth: this.netLabelWidth
|
|
1732
1753
|
});
|
|
1733
1754
|
this.testedCandidates.push(...res.testedCandidates);
|
|
1734
1755
|
if (res.placement) {
|
|
@@ -1796,7 +1817,10 @@ var SingleNetLabelPlacementSolver = class extends BaseSolver {
|
|
|
1796
1817
|
const anchors = anchorsForSegment(a, b);
|
|
1797
1818
|
for (const anchor of anchors) {
|
|
1798
1819
|
for (const orientation of candidateOrients) {
|
|
1799
|
-
const { width, height } = getDimsForOrientation(
|
|
1820
|
+
const { width, height } = getDimsForOrientation({
|
|
1821
|
+
orientation,
|
|
1822
|
+
netLabelWidth: this.netLabelWidth
|
|
1823
|
+
});
|
|
1800
1824
|
const center = getCenterFromAnchor(
|
|
1801
1825
|
anchor,
|
|
1802
1826
|
orientation,
|
|
@@ -2075,11 +2099,15 @@ var NetLabelPlacementSolver = class extends BaseSolver {
|
|
|
2075
2099
|
const isAlreadyFull = currOrients.length === 4 && fullOrients.every((o) => currOrients.includes(o));
|
|
2076
2100
|
if (!this.triedAnyOrientationFallbackForCurrentGroup && !isAlreadyFull && this.currentGroup) {
|
|
2077
2101
|
this.triedAnyOrientationFallbackForCurrentGroup = true;
|
|
2102
|
+
const netLabelWidth2 = this.currentGroup.netId ? this.inputProblem.netConnections.find(
|
|
2103
|
+
(nc) => nc.netId === this.currentGroup.netId
|
|
2104
|
+
)?.netLabelWidth : void 0;
|
|
2078
2105
|
this.activeSubSolver = new SingleNetLabelPlacementSolver({
|
|
2079
2106
|
inputProblem: this.inputProblem,
|
|
2080
2107
|
inputTraceMap: this.inputTraceMap,
|
|
2081
2108
|
overlappingSameNetTraceGroup: this.currentGroup,
|
|
2082
|
-
availableOrientations: fullOrients
|
|
2109
|
+
availableOrientations: fullOrients,
|
|
2110
|
+
netLabelWidth: netLabelWidth2
|
|
2083
2111
|
});
|
|
2084
2112
|
return;
|
|
2085
2113
|
}
|
|
@@ -2099,11 +2127,15 @@ var NetLabelPlacementSolver = class extends BaseSolver {
|
|
|
2099
2127
|
const netId = nextOverlappingSameNetTraceGroup.netId ?? nextOverlappingSameNetTraceGroup.globalConnNetId;
|
|
2100
2128
|
this.currentGroup = nextOverlappingSameNetTraceGroup;
|
|
2101
2129
|
this.triedAnyOrientationFallbackForCurrentGroup = false;
|
|
2130
|
+
const netLabelWidth = this.currentGroup.netId ? this.inputProblem.netConnections.find(
|
|
2131
|
+
(nc) => nc.netId === this.currentGroup.netId
|
|
2132
|
+
)?.netLabelWidth : void 0;
|
|
2102
2133
|
this.activeSubSolver = new SingleNetLabelPlacementSolver({
|
|
2103
2134
|
inputProblem: this.inputProblem,
|
|
2104
2135
|
inputTraceMap: this.inputTraceMap,
|
|
2105
2136
|
overlappingSameNetTraceGroup: nextOverlappingSameNetTraceGroup,
|
|
2106
|
-
availableOrientations: this.inputProblem.availableNetLabelOrientations[netId] ?? ["x+", "x-", "y+", "y-"]
|
|
2137
|
+
availableOrientations: this.inputProblem.availableNetLabelOrientations[netId] ?? ["x+", "x-", "y+", "y-"],
|
|
2138
|
+
netLabelWidth
|
|
2107
2139
|
});
|
|
2108
2140
|
}
|
|
2109
2141
|
visualize() {
|
|
@@ -273,11 +273,17 @@ export class NetLabelPlacementSolver extends BaseSolver {
|
|
|
273
273
|
this.currentGroup
|
|
274
274
|
) {
|
|
275
275
|
this.triedAnyOrientationFallbackForCurrentGroup = true
|
|
276
|
+
const netLabelWidth = this.currentGroup.netId
|
|
277
|
+
? this.inputProblem.netConnections.find(
|
|
278
|
+
(nc) => nc.netId === this.currentGroup!.netId,
|
|
279
|
+
)?.netLabelWidth
|
|
280
|
+
: undefined
|
|
276
281
|
this.activeSubSolver = new SingleNetLabelPlacementSolver({
|
|
277
282
|
inputProblem: this.inputProblem,
|
|
278
283
|
inputTraceMap: this.inputTraceMap,
|
|
279
284
|
overlappingSameNetTraceGroup: this.currentGroup,
|
|
280
285
|
availableOrientations: fullOrients,
|
|
286
|
+
netLabelWidth,
|
|
281
287
|
})
|
|
282
288
|
return
|
|
283
289
|
}
|
|
@@ -307,6 +313,12 @@ export class NetLabelPlacementSolver extends BaseSolver {
|
|
|
307
313
|
this.currentGroup = nextOverlappingSameNetTraceGroup
|
|
308
314
|
this.triedAnyOrientationFallbackForCurrentGroup = false
|
|
309
315
|
|
|
316
|
+
const netLabelWidth = this.currentGroup.netId
|
|
317
|
+
? this.inputProblem.netConnections.find(
|
|
318
|
+
(nc) => nc.netId === this.currentGroup!.netId,
|
|
319
|
+
)?.netLabelWidth
|
|
320
|
+
: undefined
|
|
321
|
+
|
|
310
322
|
this.activeSubSolver = new SingleNetLabelPlacementSolver({
|
|
311
323
|
inputProblem: this.inputProblem,
|
|
312
324
|
inputTraceMap: this.inputTraceMap,
|
|
@@ -314,6 +326,7 @@ export class NetLabelPlacementSolver extends BaseSolver {
|
|
|
314
326
|
availableOrientations: this.inputProblem.availableNetLabelOrientations[
|
|
315
327
|
netId
|
|
316
328
|
] ?? ["x+", "x-", "y+", "y-"],
|
|
329
|
+
netLabelWidth,
|
|
317
330
|
})
|
|
318
331
|
}
|
|
319
332
|
|
|
@@ -58,6 +58,9 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
58
58
|
|
|
59
59
|
chipObstacleSpatialIndex: ChipObstacleSpatialIndex
|
|
60
60
|
|
|
61
|
+
// Optional override for the width of the net label (per netId)
|
|
62
|
+
netLabelWidth?: number
|
|
63
|
+
|
|
61
64
|
netLabelPlacement: NetLabelPlacement | null = null
|
|
62
65
|
testedCandidates: Array<{
|
|
63
66
|
center: { x: number; y: number }
|
|
@@ -75,12 +78,14 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
75
78
|
inputTraceMap: Record<MspConnectionPairId, SolvedTracePath>
|
|
76
79
|
overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup
|
|
77
80
|
availableOrientations: FacingDirection[]
|
|
81
|
+
netLabelWidth?: number
|
|
78
82
|
}) {
|
|
79
83
|
super()
|
|
80
84
|
this.inputProblem = params.inputProblem
|
|
81
85
|
this.inputTraceMap = params.inputTraceMap
|
|
82
86
|
this.overlappingSameNetTraceGroup = params.overlappingSameNetTraceGroup
|
|
83
87
|
this.availableOrientations = params.availableOrientations
|
|
88
|
+
this.netLabelWidth = params.netLabelWidth
|
|
84
89
|
|
|
85
90
|
this.chipObstacleSpatialIndex =
|
|
86
91
|
params.inputProblem._chipObstacleSpatialIndex ??
|
|
@@ -95,6 +100,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
95
100
|
inputTraceMap: this.inputTraceMap,
|
|
96
101
|
overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
|
|
97
102
|
availableOrientations: this.availableOrientations,
|
|
103
|
+
netLabelWidth: this.netLabelWidth,
|
|
98
104
|
}
|
|
99
105
|
}
|
|
100
106
|
|
|
@@ -112,6 +118,7 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
112
118
|
chipObstacleSpatialIndex: this.chipObstacleSpatialIndex,
|
|
113
119
|
overlappingSameNetTraceGroup: this.overlappingSameNetTraceGroup,
|
|
114
120
|
availableOrientations: this.availableOrientations,
|
|
121
|
+
netLabelWidth: this.netLabelWidth,
|
|
115
122
|
})
|
|
116
123
|
this.testedCandidates.push(...res.testedCandidates)
|
|
117
124
|
if (res.placement) {
|
|
@@ -220,7 +227,10 @@ export class SingleNetLabelPlacementSolver extends BaseSolver {
|
|
|
220
227
|
const anchors = anchorsForSegment(a, b)
|
|
221
228
|
for (const anchor of anchors) {
|
|
222
229
|
for (const orientation of candidateOrients) {
|
|
223
|
-
const { width, height } = getDimsForOrientation(
|
|
230
|
+
const { width, height } = getDimsForOrientation({
|
|
231
|
+
orientation,
|
|
232
|
+
netLabelWidth: this.netLabelWidth,
|
|
233
|
+
})
|
|
224
234
|
const center = getCenterFromAnchor(
|
|
225
235
|
anchor,
|
|
226
236
|
orientation,
|
|
@@ -3,15 +3,25 @@ import type { FacingDirection } from "lib/utils/dir"
|
|
|
3
3
|
export const NET_LABEL_HORIZONTAL_WIDTH = 0.45
|
|
4
4
|
export const NET_LABEL_HORIZONTAL_HEIGHT = 0.2
|
|
5
5
|
|
|
6
|
-
export function getDimsForOrientation(
|
|
6
|
+
export function getDimsForOrientation(params: {
|
|
7
|
+
orientation: FacingDirection
|
|
8
|
+
netLabelWidth?: number
|
|
9
|
+
}) {
|
|
10
|
+
const { orientation, netLabelWidth } = params
|
|
11
|
+
const horizWidth =
|
|
12
|
+
typeof netLabelWidth === "number"
|
|
13
|
+
? netLabelWidth
|
|
14
|
+
: NET_LABEL_HORIZONTAL_WIDTH
|
|
15
|
+
|
|
7
16
|
if (orientation === "y+" || orientation === "y-") {
|
|
8
17
|
return {
|
|
18
|
+
// Rotated, so width/height swap
|
|
9
19
|
width: NET_LABEL_HORIZONTAL_HEIGHT,
|
|
10
|
-
height:
|
|
20
|
+
height: horizWidth,
|
|
11
21
|
}
|
|
12
22
|
}
|
|
13
23
|
return {
|
|
14
|
-
width:
|
|
24
|
+
width: horizWidth,
|
|
15
25
|
height: NET_LABEL_HORIZONTAL_HEIGHT,
|
|
16
26
|
}
|
|
17
27
|
}
|
package/lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/solvePortOnlyPin.ts
CHANGED
|
@@ -21,6 +21,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
|
|
|
21
21
|
chipObstacleSpatialIndex: ChipObstacleSpatialIndex
|
|
22
22
|
overlappingSameNetTraceGroup: OverlappingSameNetTraceGroup
|
|
23
23
|
availableOrientations: FacingDirection[]
|
|
24
|
+
netLabelWidth?: number
|
|
24
25
|
}): {
|
|
25
26
|
placement: NetLabelPlacement | null
|
|
26
27
|
testedCandidates: Array<{
|
|
@@ -41,6 +42,7 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
|
|
|
41
42
|
chipObstacleSpatialIndex,
|
|
42
43
|
overlappingSameNetTraceGroup,
|
|
43
44
|
availableOrientations,
|
|
45
|
+
netLabelWidth,
|
|
44
46
|
} = params
|
|
45
47
|
|
|
46
48
|
const pinId = overlappingSameNetTraceGroup.portOnlyPinId
|
|
@@ -98,7 +100,10 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
|
|
|
98
100
|
}> = []
|
|
99
101
|
|
|
100
102
|
for (const orientation of orientations) {
|
|
101
|
-
const { width, height } = getDimsForOrientation(
|
|
103
|
+
const { width, height } = getDimsForOrientation({
|
|
104
|
+
orientation,
|
|
105
|
+
netLabelWidth,
|
|
106
|
+
})
|
|
102
107
|
// Place label fully outside the chip: shift center slightly outward
|
|
103
108
|
const baseCenter = getCenterFromAnchor(anchor, orientation, width, height)
|
|
104
109
|
const outward = outwardOf(orientation)
|
|
@@ -176,7 +181,10 @@ export function solveNetLabelPlacementForPortOnlyPin(params: {
|
|
|
176
181
|
|
|
177
182
|
// If no valid placements found, return placement using pin's facing direction
|
|
178
183
|
const fallbackOrientation = pinFacingDirection
|
|
179
|
-
const { width, height } = getDimsForOrientation(
|
|
184
|
+
const { width, height } = getDimsForOrientation({
|
|
185
|
+
orientation: fallbackOrientation,
|
|
186
|
+
netLabelWidth,
|
|
187
|
+
})
|
|
180
188
|
const baseCenter = getCenterFromAnchor(
|
|
181
189
|
anchor,
|
|
182
190
|
fallbackOrientation,
|
|
@@ -129,11 +129,23 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
|
|
|
129
129
|
|
|
130
130
|
const { path, collisionChipIds } = state
|
|
131
131
|
|
|
132
|
+
const [PA, PB] = this.pins
|
|
132
133
|
const collision = findFirstCollision(path, this.obstacles)
|
|
133
134
|
|
|
134
135
|
if (!collision) {
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
// Sanity check: ensure path still connects PA -> PB
|
|
137
|
+
const first = path[0]!
|
|
138
|
+
const last = path[path.length - 1]!
|
|
139
|
+
const EPS = 1e-9
|
|
140
|
+
const samePoint = (p: Point, q: Point) =>
|
|
141
|
+
Math.abs(p.x - q.x) < EPS && Math.abs(p.y - q.y) < EPS
|
|
142
|
+
if (
|
|
143
|
+
samePoint(first, { x: PA.x, y: PA.y }) &&
|
|
144
|
+
samePoint(last, { x: PB.x, y: PB.y })
|
|
145
|
+
) {
|
|
146
|
+
this.solvedTracePath = path
|
|
147
|
+
this.solved = true
|
|
148
|
+
}
|
|
137
149
|
return
|
|
138
150
|
}
|
|
139
151
|
|
|
@@ -167,7 +179,7 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
|
|
|
167
179
|
return
|
|
168
180
|
}
|
|
169
181
|
|
|
170
|
-
|
|
182
|
+
// Note: PA and PB are already defined above
|
|
171
183
|
const candidates: number[] = []
|
|
172
184
|
|
|
173
185
|
if (collisionChipIds.size === 0) {
|
package/package.json
CHANGED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { PipelineDebugger } from "site/components/PipelineDebugger"
|
|
2
|
+
import type { InputProblem } from "lib/types/InputProblem"
|
|
3
|
+
|
|
4
|
+
const inputProblem: InputProblem = {
|
|
5
|
+
chips: [
|
|
6
|
+
{
|
|
7
|
+
chipId: "schematic_component_0",
|
|
8
|
+
center: {
|
|
9
|
+
x: 0,
|
|
10
|
+
y: 0,
|
|
11
|
+
},
|
|
12
|
+
width: 2,
|
|
13
|
+
height: 2,
|
|
14
|
+
pins: [
|
|
15
|
+
{
|
|
16
|
+
pinId: "CORNERS.1",
|
|
17
|
+
x: -1.4,
|
|
18
|
+
y: -0.6,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
pinId: "CORNERS.2",
|
|
22
|
+
x: -1.4,
|
|
23
|
+
y: 0.6,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
pinId: "CORNERS.3",
|
|
27
|
+
x: 1.4,
|
|
28
|
+
y: 0.6,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
pinId: "CORNERS.4",
|
|
32
|
+
x: 1.4,
|
|
33
|
+
y: -0.6,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
chipId: "schematic_component_1",
|
|
39
|
+
center: {
|
|
40
|
+
x: 4.785,
|
|
41
|
+
y: -0.3999999999999999,
|
|
42
|
+
},
|
|
43
|
+
width: 1.2000000000000002,
|
|
44
|
+
height: 1,
|
|
45
|
+
pins: [
|
|
46
|
+
{
|
|
47
|
+
pinId: "U100.1",
|
|
48
|
+
x: 3.785,
|
|
49
|
+
y: -0.29999999999999993,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
pinId: "U100.2",
|
|
53
|
+
x: 4.785,
|
|
54
|
+
y: -1.2999999999999998,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
pinId: "U100.3",
|
|
58
|
+
x: 3.785,
|
|
59
|
+
y: -0.4999999999999999,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
pinId: "U100.5",
|
|
63
|
+
x: 5.785,
|
|
64
|
+
y: -0.3999999999999999,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
chipId: "schematic_component_2",
|
|
70
|
+
center: {
|
|
71
|
+
x: 6.7,
|
|
72
|
+
y: -0.9499999999999993,
|
|
73
|
+
},
|
|
74
|
+
width: 0.53,
|
|
75
|
+
height: 1.06,
|
|
76
|
+
pins: [
|
|
77
|
+
{
|
|
78
|
+
pinId: "C101.1",
|
|
79
|
+
x: 6.7,
|
|
80
|
+
y: -0.39999999999999925,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
pinId: "C101.2",
|
|
84
|
+
x: 6.7,
|
|
85
|
+
y: -1.4999999999999993,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
chipId: "schematic_component_3",
|
|
91
|
+
center: {
|
|
92
|
+
x: 2.8699999999999997,
|
|
93
|
+
y: -1.75,
|
|
94
|
+
},
|
|
95
|
+
width: 0.53,
|
|
96
|
+
height: 1.06,
|
|
97
|
+
pins: [
|
|
98
|
+
{
|
|
99
|
+
pinId: "C100.1",
|
|
100
|
+
x: 2.8699999999999997,
|
|
101
|
+
y: -1.2,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
pinId: "C100.2",
|
|
105
|
+
x: 2.8699999999999997,
|
|
106
|
+
y: -2.3,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
chipId: "schematic_component_4",
|
|
112
|
+
center: {
|
|
113
|
+
x: 2.9752723250000006,
|
|
114
|
+
y: 0.050000000000000266,
|
|
115
|
+
},
|
|
116
|
+
width: 0.3194553499999995,
|
|
117
|
+
height: 1.06,
|
|
118
|
+
pins: [
|
|
119
|
+
{
|
|
120
|
+
pinId: "R100.1",
|
|
121
|
+
x: 2.9752723250000006,
|
|
122
|
+
y: 0.6000000000000001,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
pinId: "R100.2",
|
|
126
|
+
x: 2.9752723250000006,
|
|
127
|
+
y: -0.4999999999999998,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
directConnections: [
|
|
133
|
+
{
|
|
134
|
+
pinIds: ["C101.1", "U100.5"],
|
|
135
|
+
netId: "group > capacitor.C101 > port.pin1 to U100.VOUT",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
pinIds: ["C100.1", "U100.1"],
|
|
139
|
+
netId: "group > capacitor.C100 > port.pin1 to U100.VIN",
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
pinIds: ["R100.2", "U100.3"],
|
|
143
|
+
netId: "group > resistor.R100 > port.pin2 to U100.EN",
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
netConnections: [
|
|
147
|
+
{
|
|
148
|
+
netId: "GND",
|
|
149
|
+
pinIds: ["CORNERS.1", "CORNERS.4", "U100.2", "C101.2", "C100.2"],
|
|
150
|
+
netLabelWidth: 0.3,
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
netId: "VIN",
|
|
154
|
+
pinIds: ["CORNERS.2", "U100.1", "C100.1", "R100.1"],
|
|
155
|
+
netLabelWidth: 0.3,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
netId: "VOUT",
|
|
159
|
+
pinIds: ["CORNERS.3", "U100.5", "C101.1"],
|
|
160
|
+
netLabelWidth: 0.4,
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
netId: "LDO_EN",
|
|
164
|
+
pinIds: ["U100.3", "R100.2"],
|
|
165
|
+
netLabelWidth: 0.6,
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
availableNetLabelOrientations: {
|
|
169
|
+
GND: ["y-"],
|
|
170
|
+
VIN: ["y+"],
|
|
171
|
+
VOUT: ["y+"],
|
|
172
|
+
LDO_EN: ["x-", "x+"],
|
|
173
|
+
},
|
|
174
|
+
maxMspPairDistance: 2.4,
|
|
175
|
+
} as InputProblem
|
|
176
|
+
|
|
177
|
+
export default () => <PipelineDebugger inputProblem={inputProblem} />
|