@tscircuit/schematic-trace-solver 0.0.63 → 0.0.64
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 +1 -0
- package/dist/index.js +48 -35
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +51 -36
- package/lib/solvers/AvailableNetOrientationSolver/geometry.ts +13 -0
- package/lib/solvers/NetLabelTraceCollisionSolver/NetLabelTraceCollisionSolver.ts +9 -13
- package/package.json +1 -1
- package/tests/examples/__snapshots__/example34.snap.svg +23 -19
- package/tests/examples/example34.test.ts +8 -0
- package/tests/fixtures/traceLabelCollisions.ts +42 -0
- package/tests/repros/__snapshots__/netlabel-connector-through-rail-label.snap.svg +273 -0
- package/tests/repros/__snapshots__/trace-overlap-box-resistor.snap.svg +113 -0
- package/tests/repros/assets/repro-netlabel-connector-through-label.input.json +139 -0
- package/tests/repros/assets/repro126-trace-overlap-box-resistor.input.json +74 -0
- package/tests/repros/netlabel-connector-through-rail-label.test.ts +19 -0
- package/tests/repros/trace-overlap-box-resistor.test.ts +14 -0
package/dist/index.d.ts
CHANGED
|
@@ -704,6 +704,7 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
704
704
|
private findValidLateralShiftedCandidate;
|
|
705
705
|
private findValidCandidateInShiftColumn;
|
|
706
706
|
private evaluateCandidate;
|
|
707
|
+
private getCandidateConnectorTrace;
|
|
707
708
|
private getSearchStartAnchor;
|
|
708
709
|
private getWickOffsetAnchor;
|
|
709
710
|
private getSideOffsetAnchor;
|
package/dist/index.js
CHANGED
|
@@ -5636,6 +5636,14 @@ var tracePathCrossesAnyBounds = (tracePath, bounds) => {
|
|
|
5636
5636
|
}
|
|
5637
5637
|
return false;
|
|
5638
5638
|
};
|
|
5639
|
+
var tracePathIntersectsBounds = (tracePath, bounds) => {
|
|
5640
|
+
for (let i = 0; i < tracePath.length - 1; i++) {
|
|
5641
|
+
if (segmentIntersectsRect2(tracePath[i], tracePath[i + 1], bounds)) {
|
|
5642
|
+
return true;
|
|
5643
|
+
}
|
|
5644
|
+
}
|
|
5645
|
+
return false;
|
|
5646
|
+
};
|
|
5639
5647
|
var tracePathCrossesAnyTrace = (tracePath, traceMap) => {
|
|
5640
5648
|
for (const trace of Object.values(traceMap)) {
|
|
5641
5649
|
const points = trace.tracePath;
|
|
@@ -5900,28 +5908,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
5900
5908
|
this.addConnectorTrace(label, candidate, labelIndex);
|
|
5901
5909
|
}
|
|
5902
5910
|
addConnectorTrace(label, candidate, labelIndex) {
|
|
5903
|
-
|
|
5904
|
-
if (candidate.phase === "lateral-shift") {
|
|
5905
|
-
const orientDir = dir(candidate.orientation);
|
|
5906
|
-
const kickedSource = {
|
|
5907
|
-
x: label.anchorPoint.x - orientDir.x * LABEL_SEARCH_STEP,
|
|
5908
|
-
y: label.anchorPoint.y - orientDir.y * LABEL_SEARCH_STEP
|
|
5909
|
-
};
|
|
5910
|
-
tracePath = simplifyOrthogonalPath([
|
|
5911
|
-
label.anchorPoint,
|
|
5912
|
-
...getConnectorTracePath(
|
|
5913
|
-
kickedSource,
|
|
5914
|
-
candidate.anchorPoint,
|
|
5915
|
-
candidate.orientation
|
|
5916
|
-
)
|
|
5917
|
-
]);
|
|
5918
|
-
} else {
|
|
5919
|
-
tracePath = getConnectorTracePath(
|
|
5920
|
-
label.anchorPoint,
|
|
5921
|
-
candidate.anchorPoint,
|
|
5922
|
-
candidate.orientation
|
|
5923
|
-
);
|
|
5924
|
-
}
|
|
5911
|
+
const tracePath = this.getCandidateConnectorTrace(label, candidate);
|
|
5925
5912
|
if (tracePath.length < 2) return;
|
|
5926
5913
|
const mspPairId = `available-net-orientation-${labelIndex}-${label.netId ?? label.globalConnNetId}`;
|
|
5927
5914
|
const connectorTrace = {
|
|
@@ -6104,9 +6091,36 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
6104
6091
|
distance: distance3,
|
|
6105
6092
|
outwardDistance,
|
|
6106
6093
|
selected: false,
|
|
6107
|
-
status: this.getCandidateStatus(
|
|
6094
|
+
status: this.getCandidateStatus({
|
|
6095
|
+
candidate,
|
|
6096
|
+
label,
|
|
6097
|
+
labelIndex,
|
|
6098
|
+
phase
|
|
6099
|
+
})
|
|
6108
6100
|
};
|
|
6109
6101
|
}
|
|
6102
|
+
getCandidateConnectorTrace(label, candidate) {
|
|
6103
|
+
if (candidate.phase === "lateral-shift") {
|
|
6104
|
+
const orientDir = dir(candidate.orientation);
|
|
6105
|
+
const kickedSource = {
|
|
6106
|
+
x: label.anchorPoint.x - orientDir.x * LABEL_SEARCH_STEP,
|
|
6107
|
+
y: label.anchorPoint.y - orientDir.y * LABEL_SEARCH_STEP
|
|
6108
|
+
};
|
|
6109
|
+
return simplifyOrthogonalPath([
|
|
6110
|
+
label.anchorPoint,
|
|
6111
|
+
...getConnectorTracePath(
|
|
6112
|
+
kickedSource,
|
|
6113
|
+
candidate.anchorPoint,
|
|
6114
|
+
candidate.orientation
|
|
6115
|
+
)
|
|
6116
|
+
]);
|
|
6117
|
+
}
|
|
6118
|
+
return getConnectorTracePath(
|
|
6119
|
+
label.anchorPoint,
|
|
6120
|
+
candidate.anchorPoint,
|
|
6121
|
+
candidate.orientation
|
|
6122
|
+
);
|
|
6123
|
+
}
|
|
6110
6124
|
getSearchStartAnchor(label, orientation) {
|
|
6111
6125
|
const anchorPoint = this.getWickOffsetAnchor(label.anchorPoint, orientation);
|
|
6112
6126
|
const { width, height } = getDimsForOrientation({
|
|
@@ -6226,17 +6240,18 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
6226
6240
|
(nc) => nc.pinIds.some((pid) => label.pinIds.includes(pid))
|
|
6227
6241
|
)?.netLabelHeight;
|
|
6228
6242
|
}
|
|
6229
|
-
getCandidateStatus(
|
|
6243
|
+
getCandidateStatus(params) {
|
|
6244
|
+
const { candidate, label, labelIndex, phase } = params;
|
|
6230
6245
|
const boundsStatus = this.getBoundsStatus(
|
|
6231
6246
|
getRectBounds(candidate.center, candidate.width, candidate.height),
|
|
6232
6247
|
labelIndex
|
|
6233
6248
|
);
|
|
6234
6249
|
if (boundsStatus !== "valid") return boundsStatus;
|
|
6235
|
-
const connectorTrace =
|
|
6236
|
-
|
|
6237
|
-
candidate.
|
|
6238
|
-
|
|
6239
|
-
);
|
|
6250
|
+
const connectorTrace = this.getCandidateConnectorTrace(label, {
|
|
6251
|
+
anchorPoint: candidate.anchorPoint,
|
|
6252
|
+
orientation: candidate.orientation,
|
|
6253
|
+
phase
|
|
6254
|
+
});
|
|
6240
6255
|
if (tracePathCrossesAnyTrace(connectorTrace, this.traceMap)) {
|
|
6241
6256
|
return "trace-collision";
|
|
6242
6257
|
}
|
|
@@ -6248,7 +6263,7 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
6248
6263
|
for (let i = 0; i < this.outputNetLabelPlacements.length; i++) {
|
|
6249
6264
|
if (i === labelIndex) continue;
|
|
6250
6265
|
const otherLabel = this.outputNetLabelPlacements[i];
|
|
6251
|
-
if (
|
|
6266
|
+
if (tracePathIntersectsBounds(
|
|
6252
6267
|
connectorTrace,
|
|
6253
6268
|
getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height)
|
|
6254
6269
|
)) {
|
|
@@ -7491,16 +7506,14 @@ function buildMergedObstacleLabel(seedLabel, allLabels) {
|
|
|
7491
7506
|
height: h
|
|
7492
7507
|
};
|
|
7493
7508
|
}
|
|
7494
|
-
function
|
|
7509
|
+
function detectTraceLabelOverlaps(traces, labels) {
|
|
7495
7510
|
const overlaps = [];
|
|
7496
7511
|
for (const trace of traces) {
|
|
7497
7512
|
for (const label of labels) {
|
|
7498
7513
|
if (trace.globalConnNetId === label.globalConnNetId) continue;
|
|
7499
7514
|
const bounds = getRectBounds(label.center, label.width, label.height);
|
|
7500
7515
|
const path = trace.tracePath;
|
|
7501
|
-
|
|
7502
|
-
const innerEnd = path.length - 2;
|
|
7503
|
-
for (let i = innerStart; i < innerEnd; i++) {
|
|
7516
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
7504
7517
|
if (segmentIntersectsRect2(path[i], path[i + 1], bounds)) {
|
|
7505
7518
|
overlaps.push({ trace, label });
|
|
7506
7519
|
break;
|
|
@@ -7566,7 +7579,7 @@ var NetLabelTraceCollisionSolver = class extends BaseSolver {
|
|
|
7566
7579
|
}
|
|
7567
7580
|
return;
|
|
7568
7581
|
}
|
|
7569
|
-
const overlaps =
|
|
7582
|
+
const overlaps = detectTraceLabelOverlaps(
|
|
7570
7583
|
this.outputTraces,
|
|
7571
7584
|
this.outputNetLabelPlacements
|
|
7572
7585
|
);
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
rectsOverlap,
|
|
23
23
|
simplifyOrthogonalPath,
|
|
24
24
|
traceCrossesBoundsInterior,
|
|
25
|
+
tracePathIntersectsBounds,
|
|
25
26
|
tracePathCrossesAnyBounds,
|
|
26
27
|
tracePathCrossesAnyTrace,
|
|
27
28
|
} from "./geometry"
|
|
@@ -143,30 +144,7 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
143
144
|
candidate: EvaluatedCandidate,
|
|
144
145
|
labelIndex: number,
|
|
145
146
|
) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (candidate.phase === "lateral-shift") {
|
|
149
|
-
const orientDir = dir(candidate.orientation)
|
|
150
|
-
const kickedSource = {
|
|
151
|
-
x: label.anchorPoint.x - orientDir.x * LABEL_SEARCH_STEP,
|
|
152
|
-
y: label.anchorPoint.y - orientDir.y * LABEL_SEARCH_STEP,
|
|
153
|
-
}
|
|
154
|
-
tracePath = simplifyOrthogonalPath([
|
|
155
|
-
label.anchorPoint,
|
|
156
|
-
...getConnectorTracePath(
|
|
157
|
-
kickedSource,
|
|
158
|
-
candidate.anchorPoint,
|
|
159
|
-
candidate.orientation,
|
|
160
|
-
),
|
|
161
|
-
])
|
|
162
|
-
} else {
|
|
163
|
-
tracePath = getConnectorTracePath(
|
|
164
|
-
label.anchorPoint,
|
|
165
|
-
candidate.anchorPoint,
|
|
166
|
-
candidate.orientation,
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
|
|
147
|
+
const tracePath = this.getCandidateConnectorTrace(label, candidate)
|
|
170
148
|
if (tracePath.length < 2) return
|
|
171
149
|
|
|
172
150
|
const mspPairId = `available-net-orientation-${labelIndex}-${label.netId ?? label.globalConnNetId}`
|
|
@@ -417,8 +395,43 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
417
395
|
distance,
|
|
418
396
|
outwardDistance,
|
|
419
397
|
selected: false,
|
|
420
|
-
status: this.getCandidateStatus(
|
|
398
|
+
status: this.getCandidateStatus({
|
|
399
|
+
candidate,
|
|
400
|
+
label,
|
|
401
|
+
labelIndex,
|
|
402
|
+
phase,
|
|
403
|
+
}),
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private getCandidateConnectorTrace(
|
|
408
|
+
label: NetLabelPlacement,
|
|
409
|
+
candidate: Pick<
|
|
410
|
+
EvaluatedCandidate,
|
|
411
|
+
"anchorPoint" | "orientation" | "phase"
|
|
412
|
+
>,
|
|
413
|
+
) {
|
|
414
|
+
if (candidate.phase === "lateral-shift") {
|
|
415
|
+
const orientDir = dir(candidate.orientation)
|
|
416
|
+
const kickedSource = {
|
|
417
|
+
x: label.anchorPoint.x - orientDir.x * LABEL_SEARCH_STEP,
|
|
418
|
+
y: label.anchorPoint.y - orientDir.y * LABEL_SEARCH_STEP,
|
|
419
|
+
}
|
|
420
|
+
return simplifyOrthogonalPath([
|
|
421
|
+
label.anchorPoint,
|
|
422
|
+
...getConnectorTracePath(
|
|
423
|
+
kickedSource,
|
|
424
|
+
candidate.anchorPoint,
|
|
425
|
+
candidate.orientation,
|
|
426
|
+
),
|
|
427
|
+
])
|
|
421
428
|
}
|
|
429
|
+
|
|
430
|
+
return getConnectorTracePath(
|
|
431
|
+
label.anchorPoint,
|
|
432
|
+
candidate.anchorPoint,
|
|
433
|
+
candidate.orientation,
|
|
434
|
+
)
|
|
422
435
|
}
|
|
423
436
|
|
|
424
437
|
private getSearchStartAnchor(
|
|
@@ -583,22 +596,24 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
583
596
|
)?.netLabelHeight
|
|
584
597
|
}
|
|
585
598
|
|
|
586
|
-
private getCandidateStatus(
|
|
587
|
-
candidate: CandidateLabel
|
|
588
|
-
label: NetLabelPlacement
|
|
589
|
-
labelIndex: number
|
|
590
|
-
|
|
599
|
+
private getCandidateStatus(params: {
|
|
600
|
+
candidate: CandidateLabel
|
|
601
|
+
label: NetLabelPlacement
|
|
602
|
+
labelIndex: number
|
|
603
|
+
phase: CandidatePhase
|
|
604
|
+
}) {
|
|
605
|
+
const { candidate, label, labelIndex, phase } = params
|
|
591
606
|
const boundsStatus = this.getBoundsStatus(
|
|
592
607
|
getRectBounds(candidate.center, candidate.width, candidate.height),
|
|
593
608
|
labelIndex,
|
|
594
609
|
)
|
|
595
610
|
if (boundsStatus !== "valid") return boundsStatus
|
|
596
611
|
|
|
597
|
-
const connectorTrace =
|
|
598
|
-
|
|
599
|
-
candidate.
|
|
600
|
-
|
|
601
|
-
)
|
|
612
|
+
const connectorTrace = this.getCandidateConnectorTrace(label, {
|
|
613
|
+
anchorPoint: candidate.anchorPoint,
|
|
614
|
+
orientation: candidate.orientation,
|
|
615
|
+
phase,
|
|
616
|
+
})
|
|
602
617
|
|
|
603
618
|
if (tracePathCrossesAnyTrace(connectorTrace, this.traceMap)) {
|
|
604
619
|
return "trace-collision"
|
|
@@ -614,7 +629,7 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
614
629
|
if (i === labelIndex) continue
|
|
615
630
|
const otherLabel = this.outputNetLabelPlacements[i]!
|
|
616
631
|
if (
|
|
617
|
-
|
|
632
|
+
tracePathIntersectsBounds(
|
|
618
633
|
connectorTrace,
|
|
619
634
|
getRectBounds(otherLabel.center, otherLabel.width, otherLabel.height),
|
|
620
635
|
)
|
|
@@ -2,6 +2,7 @@ import type { Point } from "@tscircuit/math-utils"
|
|
|
2
2
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
3
3
|
import type { InputProblem } from "lib/types/InputProblem"
|
|
4
4
|
import type { FacingDirection } from "lib/utils/dir"
|
|
5
|
+
import { segmentIntersectsRect } from "lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions"
|
|
5
6
|
import { EPS, TRACE_BOUNDARY_TOLERANCE } from "./constants"
|
|
6
7
|
import type { Bounds, ChipSide } from "./types"
|
|
7
8
|
|
|
@@ -102,6 +103,18 @@ export const tracePathCrossesAnyBounds = (
|
|
|
102
103
|
return false
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
export const tracePathIntersectsBounds = (
|
|
107
|
+
tracePath: Point[],
|
|
108
|
+
bounds: Bounds,
|
|
109
|
+
) => {
|
|
110
|
+
for (let i = 0; i < tracePath.length - 1; i++) {
|
|
111
|
+
if (segmentIntersectsRect(tracePath[i]!, tracePath[i + 1]!, bounds)) {
|
|
112
|
+
return true
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
|
|
105
118
|
export const tracePathCrossesAnyTrace = (
|
|
106
119
|
tracePath: Point[],
|
|
107
120
|
traceMap: Record<string, SolvedTracePath>,
|
|
@@ -72,31 +72,27 @@ function buildMergedObstacleLabel(
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
interface
|
|
75
|
+
interface TraceLabelOverlap {
|
|
76
76
|
trace: SolvedTracePath
|
|
77
77
|
label: NetLabelPlacement
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* Detects overlaps where a trace
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* Detects overlaps where a trace segment intersects a label from another net.
|
|
82
|
+
* Point-only contact is allowed by segmentIntersectsRect; positive overlap on
|
|
83
|
+
* a label edge is still a visual collision and should be rerouted.
|
|
84
84
|
*/
|
|
85
|
-
function
|
|
85
|
+
function detectTraceLabelOverlaps(
|
|
86
86
|
traces: SolvedTracePath[],
|
|
87
87
|
labels: NetLabelPlacement[],
|
|
88
|
-
):
|
|
89
|
-
const overlaps:
|
|
88
|
+
): TraceLabelOverlap[] {
|
|
89
|
+
const overlaps: TraceLabelOverlap[] = []
|
|
90
90
|
for (const trace of traces) {
|
|
91
91
|
for (const label of labels) {
|
|
92
92
|
if (trace.globalConnNetId === label.globalConnNetId) continue
|
|
93
93
|
const bounds = getRectBounds(label.center, label.width, label.height)
|
|
94
94
|
const path = trace.tracePath
|
|
95
|
-
|
|
96
|
-
// sit inside or adjacent to labels of neighbouring nets.
|
|
97
|
-
const innerStart = 1
|
|
98
|
-
const innerEnd = path.length - 2
|
|
99
|
-
for (let i = innerStart; i < innerEnd; i++) {
|
|
95
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
100
96
|
if (segmentIntersectsRect(path[i]!, path[i + 1]!, bounds)) {
|
|
101
97
|
overlaps.push({ trace, label })
|
|
102
98
|
break
|
|
@@ -183,7 +179,7 @@ export class NetLabelTraceCollisionSolver extends BaseSolver {
|
|
|
183
179
|
return
|
|
184
180
|
}
|
|
185
181
|
|
|
186
|
-
const overlaps =
|
|
182
|
+
const overlaps = detectTraceLabelOverlaps(
|
|
187
183
|
this.outputTraces,
|
|
188
184
|
this.outputNetLabelPlacements,
|
|
189
185
|
)
|
package/package.json
CHANGED
|
@@ -2,56 +2,60 @@
|
|
|
2
2
|
<rect width="100%" height="100%" fill="white" />
|
|
3
3
|
<g>
|
|
4
4
|
<circle data-type="point" data-label="U1.1
|
|
5
|
-
x+" data-x="1.1" data-y="0.30000000000000004" cx="
|
|
5
|
+
x+" data-x="1.1" data-y="0.30000000000000004" cx="479.84291324526953" cy="250.0249910746162" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
|
|
6
6
|
</g>
|
|
7
7
|
<g>
|
|
8
8
|
<circle data-type="point" data-label="U1.2
|
|
9
|
-
x+" data-x="1.1" data-y="0.09999999999999998" cx="
|
|
9
|
+
x+" data-x="1.1" data-y="0.09999999999999998" cx="479.84291324526953" cy="290.0107104605498" r="3" fill="hsl(320, 100%, 50%, 0.8)" />
|
|
10
10
|
</g>
|
|
11
11
|
<g>
|
|
12
12
|
<circle data-type="point" data-label="U1.3
|
|
13
|
-
x+" data-x="1.1" data-y="-0.10000000000000003" cx="
|
|
13
|
+
x+" data-x="1.1" data-y="-0.10000000000000003" cx="479.84291324526953" cy="329.9964298464834" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
|
|
14
14
|
</g>
|
|
15
15
|
<g>
|
|
16
16
|
<circle data-type="point" data-label="U1.4
|
|
17
|
-
x+" data-x="1.1" data-y="-0.30000000000000004" cx="
|
|
17
|
+
x+" data-x="1.1" data-y="-0.30000000000000004" cx="479.84291324526953" cy="369.982149232417" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
|
|
18
18
|
</g>
|
|
19
19
|
<g>
|
|
20
|
-
<circle data-type="point" data-label="
|
|
20
|
+
<circle data-type="point" data-label="anchorPoint
|
|
21
|
+
orientation: x+" data-x="1.1" data-y="0.30000000000000004" cx="479.84291324526953" cy="250.0249910746162" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
21
22
|
</g>
|
|
22
23
|
<g>
|
|
23
|
-
<circle data-type="point" data-label="
|
|
24
|
+
<circle data-type="point" data-label="anchorPoint
|
|
25
|
+
orientation: x+" data-x="1.1" data-y="0.09999999999999998" cx="479.84291324526953" cy="290.0107104605498" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
24
26
|
</g>
|
|
25
27
|
<g>
|
|
26
|
-
<circle data-type="point" data-label="
|
|
28
|
+
<circle data-type="point" data-label="anchorPoint
|
|
29
|
+
orientation: y+" data-x="1.601" data-y="0.4009999999999999" cx="580.0071403070332" cy="229.83220278471975" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
27
30
|
</g>
|
|
28
31
|
<g>
|
|
29
|
-
<circle data-type="point" data-label="
|
|
32
|
+
<circle data-type="point" data-label="anchorPoint
|
|
33
|
+
orientation: y-" data-x="1.201" data-y="-0.5010000000000001" cx="500.035701535166" cy="410.1677972152803" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
30
34
|
</g>
|
|
31
35
|
<g>
|
|
32
|
-
<polyline data-points="1.1,-0.10000000000000003 1.
|
|
36
|
+
<polyline data-points="1.1,-0.10000000000000003 1.601,-0.10000000000000003 1.601,0.4009999999999999" data-type="line" data-label="" points="479.84291324526953,329.9964298464834 580.0071403070332,329.9964298464834 580.0071403070332,229.83220278471975" fill="none" stroke="purple" stroke-width="1" />
|
|
33
37
|
</g>
|
|
34
38
|
<g>
|
|
35
|
-
<polyline data-points="1.1,-0.30000000000000004 1.201,-0.30000000000000004 1.201,-0.5010000000000001" data-type="line" data-label="" points="
|
|
39
|
+
<polyline data-points="1.1,-0.30000000000000004 1.201,-0.30000000000000004 1.201,-0.5010000000000001" data-type="line" data-label="" points="479.84291324526953,369.982149232417 500.035701535166,369.982149232417 500.035701535166,410.1677972152803" fill="none" stroke="purple" stroke-width="1" />
|
|
36
40
|
</g>
|
|
37
41
|
<g>
|
|
38
|
-
<rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="
|
|
42
|
+
<rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="39.99999999999997" y="210.03927168868262" width="439.84291324526953" height="199.92859692966795" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.005001785714285715" />
|
|
39
43
|
</g>
|
|
40
44
|
<g>
|
|
41
45
|
<rect data-type="rect" data-label="netId: SCL
|
|
42
|
-
globalConnNetId: connectivity_net0" data-x="1.326" data-y="0.30000000000000004" x="
|
|
46
|
+
globalConnNetId: connectivity_net0" data-x="1.326" data-y="0.30000000000000004" x="480.0428418421992" y="230.03213138164938" width="89.96786861835062" height="39.985719385933635" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.005001785714285715" />
|
|
43
47
|
</g>
|
|
44
48
|
<g>
|
|
45
49
|
<rect data-type="rect" data-label="netId: SDA
|
|
46
|
-
globalConnNetId: connectivity_net1" data-x="1.326" data-y="0.09999999999999998" x="
|
|
50
|
+
globalConnNetId: connectivity_net1" data-x="1.326" data-y="0.09999999999999998" x="480.0428418421992" y="270.017850767583" width="89.96786861835062" height="39.98571938593358" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.005001785714285715" />
|
|
47
51
|
</g>
|
|
48
52
|
<g>
|
|
49
53
|
<rect data-type="rect" data-label="netId: V3_3
|
|
50
|
-
globalConnNetId: connectivity_net2" data-x="1.
|
|
54
|
+
globalConnNetId: connectivity_net2" data-x="1.601" data-y="0.6259999999999999" x="560.0142806140664" y="139.86433416636916" width="39.985719385933635" height="89.9678686183506" fill="#ef444466" stroke="#ef4444" stroke-width="0.005001785714285715" />
|
|
51
55
|
</g>
|
|
52
56
|
<g>
|
|
53
57
|
<rect data-type="rect" data-label="netId: GND
|
|
54
|
-
globalConnNetId: connectivity_net3" data-x="1.201" data-y="-0.7260000000000001" x="
|
|
58
|
+
globalConnNetId: connectivity_net3" data-x="1.201" data-y="-0.7260000000000001" x="480.0428418421992" y="410.1677972152803" width="39.985719385933635" height="89.96786861835051" fill="#00000066" stroke="#000000" stroke-width="0.005001785714285715" />
|
|
55
59
|
</g>
|
|
56
60
|
<g id="crosshair" style="display: none">
|
|
57
61
|
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
@@ -81,12 +85,12 @@ globalConnNetId: connectivity_net3" data-x="1.201" data-y="-0.7260000000000001"
|
|
|
81
85
|
|
|
82
86
|
// Calculate real coordinates using inverse transformation
|
|
83
87
|
const matrix = {
|
|
84
|
-
"a":
|
|
88
|
+
"a": 199.92859692966798,
|
|
85
89
|
"c": 0,
|
|
86
|
-
"e":
|
|
90
|
+
"e": 259.92145662263476,
|
|
87
91
|
"b": 0,
|
|
88
|
-
"d": -
|
|
89
|
-
"f":
|
|
92
|
+
"d": -199.92859692966798,
|
|
93
|
+
"f": 310.0035701535166
|
|
90
94
|
};
|
|
91
95
|
// Manually invert and apply the affine transform
|
|
92
96
|
// Since we only use translate and scale, we can directly compute:
|
|
@@ -2,11 +2,19 @@ import { test, expect } from "bun:test"
|
|
|
2
2
|
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
3
|
import inputProblem from "../assets/example34.json"
|
|
4
4
|
import "tests/fixtures/matcher"
|
|
5
|
+
import { getTraceLabelCollisions } from "tests/fixtures/traceLabelCollisions"
|
|
5
6
|
|
|
6
7
|
test("example34", () => {
|
|
7
8
|
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
9
|
|
|
9
10
|
solver.solve()
|
|
10
11
|
|
|
12
|
+
expect(
|
|
13
|
+
getTraceLabelCollisions(
|
|
14
|
+
solver.netLabelNetLabelCollisionSolver!.traces,
|
|
15
|
+
solver.netLabelNetLabelCollisionSolver!.outputNetLabelPlacements,
|
|
16
|
+
),
|
|
17
|
+
).toEqual([])
|
|
18
|
+
|
|
11
19
|
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
12
20
|
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
2
|
+
import { getRectBounds } from "lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/geometry"
|
|
3
|
+
import { segmentIntersectsRect } from "lib/solvers/NetLabelPlacementSolver/SingleNetLabelPlacementSolver/collisions"
|
|
4
|
+
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
5
|
+
|
|
6
|
+
export const getTraceLabelCollisions = (
|
|
7
|
+
traces: SolvedTracePath[],
|
|
8
|
+
labels: NetLabelPlacement[],
|
|
9
|
+
) => {
|
|
10
|
+
const collisions: Array<{
|
|
11
|
+
traceId: string
|
|
12
|
+
traceNetId: string
|
|
13
|
+
labelNetId: string
|
|
14
|
+
segmentIndex: number
|
|
15
|
+
}> = []
|
|
16
|
+
|
|
17
|
+
for (const trace of traces) {
|
|
18
|
+
for (const label of labels) {
|
|
19
|
+
if (trace.globalConnNetId === label.globalConnNetId) continue
|
|
20
|
+
|
|
21
|
+
const bounds = getRectBounds(label.center, label.width, label.height)
|
|
22
|
+
for (let i = 0; i < trace.tracePath.length - 1; i++) {
|
|
23
|
+
if (
|
|
24
|
+
segmentIntersectsRect(
|
|
25
|
+
trace.tracePath[i]!,
|
|
26
|
+
trace.tracePath[i + 1]!,
|
|
27
|
+
bounds,
|
|
28
|
+
)
|
|
29
|
+
) {
|
|
30
|
+
collisions.push({
|
|
31
|
+
traceId: trace.mspPairId,
|
|
32
|
+
traceNetId: trace.globalConnNetId,
|
|
33
|
+
labelNetId: label.globalConnNetId,
|
|
34
|
+
segmentIndex: i,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return collisions
|
|
42
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
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.3
|
|
5
|
+
x+" data-x="3.3774999999999995" data-y="-2.7900000000000005" cx="574.6987951807228" cy="508.49397590361446" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
|
|
6
|
+
</g>
|
|
7
|
+
<g>
|
|
8
|
+
<circle data-type="point" data-label="U1.7
|
|
9
|
+
x-" data-x="0.3774999999999997" data-y="-1.39" cx="321.6867469879518" cy="390.4216867469879" r="3" fill="hsl(325, 100%, 50%, 0.8)" />
|
|
10
|
+
</g>
|
|
11
|
+
<g>
|
|
12
|
+
<circle data-type="point" data-label="U1.10
|
|
13
|
+
x-" data-x="0.3774999999999997" data-y="0.3100000000000005" cx="321.6867469879518" cy="247.04819277108427" r="3" fill="hsl(217, 100%, 50%, 0.8)" />
|
|
14
|
+
</g>
|
|
15
|
+
<g>
|
|
16
|
+
<circle data-type="point" data-label="U1.13
|
|
17
|
+
x-" data-x="0.3774999999999997" data-y="-0.1899999999999995" cx="321.6867469879518" cy="289.21686746987945" r="3" fill="hsl(220, 100%, 50%, 0.8)" />
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
<circle data-type="point" data-label="U1.18
|
|
21
|
+
x+" data-x="3.3774999999999995" data-y="-2.5900000000000003" cx="574.6987951807228" cy="491.6265060240964" r="3" fill="hsl(225, 100%, 50%, 0.8)" />
|
|
22
|
+
</g>
|
|
23
|
+
<g>
|
|
24
|
+
<circle data-type="point" data-label="U1.22
|
|
25
|
+
x+" data-x="3.3774999999999995" data-y="1.7100000000000004" cx="574.6987951807228" cy="128.97590361445776" r="3" fill="hsl(250, 100%, 50%, 0.8)" />
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
<circle data-type="point" data-label="U1.28
|
|
29
|
+
x+" data-x="3.3774999999999995" data-y="1.5100000000000002" cx="574.6987951807228" cy="145.84337349397586" r="3" fill="hsl(256, 100%, 50%, 0.8)" />
|
|
30
|
+
</g>
|
|
31
|
+
<g>
|
|
32
|
+
<circle data-type="point" data-label="U1.29
|
|
33
|
+
x+" data-x="3.3774999999999995" data-y="-2.3900000000000006" cx="574.6987951807228" cy="474.7590361445783" r="3" fill="hsl(257, 100%, 50%, 0.8)" />
|
|
34
|
+
</g>
|
|
35
|
+
<g>
|
|
36
|
+
<circle data-type="point" data-label="J2.1
|
|
37
|
+
x-" data-x="-1.2225000000000006" data-y="0.6600000000000018" cx="186.74698795180717" cy="217.53012048192753" r="3" fill="hsl(99, 100%, 50%, 0.8)" />
|
|
38
|
+
</g>
|
|
39
|
+
<g>
|
|
40
|
+
<circle data-type="point" data-label="J2.2
|
|
41
|
+
y-" data-x="-0.7725000000000006" data-y="0.2950000000000018" cx="224.6987951807228" cy="248.31325301204802" r="3" fill="hsl(100, 100%, 50%, 0.8)" />
|
|
42
|
+
</g>
|
|
43
|
+
<g>
|
|
44
|
+
<circle data-type="point" data-label="J2.3
|
|
45
|
+
x+" data-x="-0.3225000000000006" data-y="0.6600000000000018" cx="262.6506024096385" cy="217.53012048192753" r="3" fill="hsl(101, 100%, 50%, 0.8)" />
|
|
46
|
+
</g>
|
|
47
|
+
<g>
|
|
48
|
+
<circle data-type="point" data-label="J3.1
|
|
49
|
+
y-" data-x="-2.4125" data-y="-1.84" cx="86.38554216867468" cy="428.37349397590356" r="3" fill="hsl(340, 100%, 50%, 0.8)" />
|
|
50
|
+
</g>
|
|
51
|
+
<g>
|
|
52
|
+
<circle data-type="point" data-label="J3.2
|
|
53
|
+
x+" data-x="-2.0475" data-y="-1.39" cx="117.16867469879517" cy="390.4216867469879" r="3" fill="hsl(341, 100%, 50%, 0.8)" />
|
|
54
|
+
</g>
|
|
55
|
+
<g>
|
|
56
|
+
<circle data-type="point" data-label="J3.3
|
|
57
|
+
y+" data-x="-2.4125" data-y="-0.9399999999999997" cx="86.38554216867468" cy="352.4698795180722" r="3" fill="hsl(342, 100%, 50%, 0.8)" />
|
|
58
|
+
</g>
|
|
59
|
+
<g>
|
|
60
|
+
<circle data-type="point" data-label="anchorPoint
|
|
61
|
+
orientation: y-" data-x="3.5774999999999997" data-y="-2.7900000000000005" cx="591.566265060241" cy="508.49397590361446" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
62
|
+
</g>
|
|
63
|
+
<g>
|
|
64
|
+
<circle data-type="point" data-label="anchorPoint
|
|
65
|
+
orientation: y-" data-x="0.20249999999999962" data-y="-0.1899999999999995" cx="306.92771084337346" cy="289.21686746987945" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
66
|
+
</g>
|
|
67
|
+
<g>
|
|
68
|
+
<circle data-type="point" data-label="anchorPoint
|
|
69
|
+
orientation: y-" data-x="-2.7125000000000004" data-y="-0.9909999999999998" cx="61.08433734939754" cy="356.77108433734935" 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="-0.8350000000000001" data-y="-1.39" cx="219.42771084337346" cy="390.4216867469879" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
74
|
+
</g>
|
|
75
|
+
<g>
|
|
76
|
+
<circle data-type="point" data-label="anchorPoint
|
|
77
|
+
orientation: x-" data-x="-0.7725000000000006" data-y="0.09500000000000186" cx="224.6987951807228" cy="265.18072289156606" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
78
|
+
</g>
|
|
79
|
+
<g>
|
|
80
|
+
<circle data-type="point" data-label="anchorPoint
|
|
81
|
+
orientation: y-" data-x="3.5774999999999997" data-y="1.5100000000000002" cx="591.566265060241" cy="145.84337349397586" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
82
|
+
</g>
|
|
83
|
+
<g>
|
|
84
|
+
<circle data-type="point" data-label="anchorPoint
|
|
85
|
+
orientation: y+" data-x="-1.3235000000000006" data-y="0.8610000000000018" cx="178.22891566265054" cy="200.57831325301186" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
86
|
+
</g>
|
|
87
|
+
<g>
|
|
88
|
+
<circle data-type="point" data-label="anchorPoint
|
|
89
|
+
orientation: y+" data-x="-2.8625000000000003" data-y="-0.989" cx="48.433734939759006" cy="356.6024096385542" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
90
|
+
</g>
|
|
91
|
+
<g>
|
|
92
|
+
<polyline data-points="3.3774999999999995,1.5100000000000002 3.3774999999999995,1.7100000000000004" data-type="line" data-label="" points="574.6987951807228,145.84337349397586 574.6987951807228,128.97590361445776" fill="none" stroke="hsl(176, 100%, 50%, 0.8)" stroke-width="1" />
|
|
93
|
+
</g>
|
|
94
|
+
<g>
|
|
95
|
+
<polyline data-points="-0.7725000000000006,0.2950000000000018 0.3774999999999997,0.3100000000000005" data-type="line" data-label="" points="224.6987951807228,248.31325301204802 321.6867469879518,247.04819277108427" fill="none" stroke="hsl(48, 100%, 50%, 0.8)" stroke-width="1" />
|
|
96
|
+
</g>
|
|
97
|
+
<g>
|
|
98
|
+
<polyline data-points="-2.0475,-1.39 0.3774999999999997,-1.39" data-type="line" data-label="" points="117.16867469879517,390.4216867469879 321.6867469879518,390.4216867469879" fill="none" stroke="hsl(312, 100%, 50%, 0.8)" stroke-width="1" />
|
|
99
|
+
</g>
|
|
100
|
+
<g>
|
|
101
|
+
<polyline data-points="3.3774999999999995,-2.7900000000000005 0.3774999999999997,-0.1899999999999995" data-type="line" data-label="" points="574.6987951807228,508.49397590361446 321.6867469879518,289.21686746987945" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
102
|
+
</g>
|
|
103
|
+
<g>
|
|
104
|
+
<polyline data-points="3.3774999999999995,-2.7900000000000005 3.3774999999999995,-2.5900000000000003" data-type="line" data-label="" points="574.6987951807228,508.49397590361446 574.6987951807228,491.6265060240964" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
105
|
+
</g>
|
|
106
|
+
<g>
|
|
107
|
+
<polyline data-points="3.3774999999999995,-2.7900000000000005 3.3774999999999995,-2.3900000000000006" data-type="line" data-label="" points="574.6987951807228,508.49397590361446 574.6987951807228,474.7590361445783" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
108
|
+
</g>
|
|
109
|
+
<g>
|
|
110
|
+
<polyline data-points="3.3774999999999995,-2.7900000000000005 -0.3225000000000006,0.6600000000000018" data-type="line" data-label="" points="574.6987951807228,508.49397590361446 262.6506024096385,217.53012048192753" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
111
|
+
</g>
|
|
112
|
+
<g>
|
|
113
|
+
<polyline data-points="3.3774999999999995,-2.7900000000000005 -2.4125,-0.9399999999999997" data-type="line" data-label="" points="574.6987951807228,508.49397590361446 86.38554216867468,352.4698795180722" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
114
|
+
</g>
|
|
115
|
+
<g>
|
|
116
|
+
<polyline data-points="0.3774999999999997,-0.1899999999999995 3.3774999999999995,-2.5900000000000003" data-type="line" data-label="" points="321.6867469879518,289.21686746987945 574.6987951807228,491.6265060240964" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
117
|
+
</g>
|
|
118
|
+
<g>
|
|
119
|
+
<polyline data-points="0.3774999999999997,-0.1899999999999995 3.3774999999999995,-2.3900000000000006" data-type="line" data-label="" points="321.6867469879518,289.21686746987945 574.6987951807228,474.7590361445783" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
120
|
+
</g>
|
|
121
|
+
<g>
|
|
122
|
+
<polyline data-points="0.3774999999999997,-0.1899999999999995 -0.3225000000000006,0.6600000000000018" data-type="line" data-label="" points="321.6867469879518,289.21686746987945 262.6506024096385,217.53012048192753" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
123
|
+
</g>
|
|
124
|
+
<g>
|
|
125
|
+
<polyline data-points="0.3774999999999997,-0.1899999999999995 -2.4125,-0.9399999999999997" data-type="line" data-label="" points="321.6867469879518,289.21686746987945 86.38554216867468,352.4698795180722" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
126
|
+
</g>
|
|
127
|
+
<g>
|
|
128
|
+
<polyline data-points="3.3774999999999995,-2.5900000000000003 3.3774999999999995,-2.3900000000000006" data-type="line" data-label="" points="574.6987951807228,491.6265060240964 574.6987951807228,474.7590361445783" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
129
|
+
</g>
|
|
130
|
+
<g>
|
|
131
|
+
<polyline data-points="3.3774999999999995,-2.5900000000000003 -0.3225000000000006,0.6600000000000018" data-type="line" data-label="" points="574.6987951807228,491.6265060240964 262.6506024096385,217.53012048192753" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
132
|
+
</g>
|
|
133
|
+
<g>
|
|
134
|
+
<polyline data-points="3.3774999999999995,-2.5900000000000003 -2.4125,-0.9399999999999997" data-type="line" data-label="" points="574.6987951807228,491.6265060240964 86.38554216867468,352.4698795180722" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
135
|
+
</g>
|
|
136
|
+
<g>
|
|
137
|
+
<polyline data-points="3.3774999999999995,-2.3900000000000006 -0.3225000000000006,0.6600000000000018" data-type="line" data-label="" points="574.6987951807228,474.7590361445783 262.6506024096385,217.53012048192753" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
138
|
+
</g>
|
|
139
|
+
<g>
|
|
140
|
+
<polyline data-points="3.3774999999999995,-2.3900000000000006 -2.4125,-0.9399999999999997" data-type="line" data-label="" points="574.6987951807228,474.7590361445783 86.38554216867468,352.4698795180722" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
141
|
+
</g>
|
|
142
|
+
<g>
|
|
143
|
+
<polyline data-points="-0.3225000000000006,0.6600000000000018 -2.4125,-0.9399999999999997" data-type="line" data-label="" points="262.6506024096385,217.53012048192753 86.38554216867468,352.4698795180722" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
144
|
+
</g>
|
|
145
|
+
<g>
|
|
146
|
+
<polyline data-points="-1.2225000000000006,0.6600000000000018 -2.4125,-1.84" data-type="line" data-label="" points="186.74698795180717,217.53012048192753 86.38554216867468,428.37349397590356" fill="none" stroke="hsl(186, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
147
|
+
</g>
|
|
148
|
+
<g>
|
|
149
|
+
<polyline data-points="3.3774999999999995,1.5100000000000002 3.5774999999999997,1.5100000000000002 3.5774999999999997,1.7100000000000004 3.3774999999999995,1.7100000000000004" data-type="line" data-label="" points="574.6987951807228,145.84337349397586 591.566265060241,145.84337349397586 591.566265060241,128.97590361445776 574.6987951807228,128.97590361445776" fill="none" stroke="purple" stroke-width="1" />
|
|
150
|
+
</g>
|
|
151
|
+
<g>
|
|
152
|
+
<polyline data-points="-0.7725000000000006,0.2950000000000018 -0.7725000000000006,0.09500000000000186 0.17749999999999966,0.09500000000000186 0.17749999999999966,0.3100000000000005 0.3774999999999997,0.3100000000000005" data-type="line" data-label="" points="224.6987951807228,248.31325301204802 224.6987951807228,265.18072289156606 304.8192771084337,265.18072289156606 304.8192771084337,247.04819277108427 321.6867469879518,247.04819277108427" fill="none" stroke="purple" stroke-width="1" />
|
|
153
|
+
</g>
|
|
154
|
+
<g>
|
|
155
|
+
<polyline data-points="0.3774999999999997,-0.1899999999999995 0.027499999999999553,-0.1899999999999995 0.027499999999999553,0.6600000000000018 -0.3225000000000006,0.6600000000000018" data-type="line" data-label="" points="321.6867469879518,289.21686746987945 292.16867469879514,289.21686746987945 292.16867469879514,217.53012048192753 262.6506024096385,217.53012048192753" fill="none" stroke="purple" stroke-width="1" />
|
|
156
|
+
</g>
|
|
157
|
+
<g>
|
|
158
|
+
<polyline data-points="3.3774999999999995,-2.3900000000000006 3.5774999999999997,-2.3900000000000006 3.5774999999999997,-2.5900000000000003 3.3774999999999995,-2.5900000000000003" data-type="line" data-label="" points="574.6987951807228,474.7590361445783 591.566265060241,474.7590361445783 591.566265060241,491.6265060240964 574.6987951807228,491.6265060240964" fill="none" stroke="purple" stroke-width="1" />
|
|
159
|
+
</g>
|
|
160
|
+
<g>
|
|
161
|
+
<polyline data-points="3.3774999999999995,-2.7900000000000005 3.5774999999999997,-2.7900000000000005 3.5774999999999997,-2.5900000000000003 3.3774999999999995,-2.5900000000000003" data-type="line" data-label="" points="574.6987951807228,508.49397590361446 591.566265060241,508.49397590361446 591.566265060241,491.6265060240964 574.6987951807228,491.6265060240964" fill="none" stroke="purple" stroke-width="1" />
|
|
162
|
+
</g>
|
|
163
|
+
<g>
|
|
164
|
+
<polyline data-points="-2.0475,-1.39 0.3774999999999997,-1.39" data-type="line" data-label="" points="117.16867469879517,390.4216867469879 321.6867469879518,390.4216867469879" fill="none" stroke="purple" stroke-width="1" />
|
|
165
|
+
</g>
|
|
166
|
+
<g>
|
|
167
|
+
<polyline data-points="-2.4125,-0.9399999999999997 -2.4125,-0.8899999999999997 -2.7125000000000004,-0.8899999999999997 -2.7125000000000004,-0.9909999999999998" data-type="line" data-label="" points="86.38554216867468,352.4698795180722 86.38554216867468,348.2530120481927 61.08433734939754,348.2530120481927 61.08433734939754,356.77108433734935" fill="none" stroke="purple" stroke-width="1" />
|
|
168
|
+
</g>
|
|
169
|
+
<g>
|
|
170
|
+
<polyline data-points="-1.2225000000000006,0.6600000000000018 -1.3235000000000006,0.6600000000000018 -1.3235000000000006,0.8610000000000018" data-type="line" data-label="" points="186.74698795180717,217.53012048192753 178.22891566265054,217.53012048192753 178.22891566265054,200.57831325301186" fill="none" stroke="purple" stroke-width="1" />
|
|
171
|
+
</g>
|
|
172
|
+
<g>
|
|
173
|
+
<polyline data-points="-2.4125,-1.84 -2.4125,-1.8900000000000001 -2.8625000000000003,-1.8900000000000001 -2.8625000000000003,-0.989" data-type="line" data-label="" points="86.38554216867468,428.37349397590356 86.38554216867468,432.5903614457831 48.433734939759006,432.5903614457831 48.433734939759006,356.6024096385542" fill="none" stroke="purple" stroke-width="1" />
|
|
174
|
+
</g>
|
|
175
|
+
<g>
|
|
176
|
+
<rect data-type="rect" data-label="schematic_component_0" data-x="1.8774999999999997" data-y="-0.43999999999999995" x="321.6867469879518" y="91.02409638554212" width="253.01204819277098" height="438.55421686746996" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011857142857142858" />
|
|
177
|
+
</g>
|
|
178
|
+
<g>
|
|
179
|
+
<rect data-type="rect" data-label="schematic_component_6" data-x="-0.7725000000000006" data-y="0.5600000000000018" x="186.74698795180717" y="203.61445783132513" width="75.90361445783134" height="44.6987951807229" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011857142857142858" />
|
|
180
|
+
</g>
|
|
181
|
+
<g>
|
|
182
|
+
<rect data-type="rect" data-label="schematic_component_7" data-x="-2.3125" data-y="-1.39" x="72.46987951807228" y="352.4698795180722" width="44.6987951807229" height="75.90361445783134" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011857142857142858" />
|
|
183
|
+
</g>
|
|
184
|
+
<g>
|
|
185
|
+
<rect data-type="rect" data-label="netId: GND
|
|
186
|
+
globalConnNetId: connectivity_net3" data-x="3.5774999999999997" data-y="-3.0300000000000002" x="583.1325301204819" y="508.49397590361446" width="16.867469879518126" height="40.481927710843365" fill="#00000066" stroke="#000000" stroke-width="0.011857142857142858" />
|
|
187
|
+
</g>
|
|
188
|
+
<g>
|
|
189
|
+
<rect data-type="rect" data-label="netId: GND
|
|
190
|
+
globalConnNetId: connectivity_net3" data-x="0.20249999999999962" data-y="-0.4299999999999995" x="298.4939759036144" y="289.21686746987945" width="16.86746987951807" height="40.481927710843365" fill="#00000066" stroke="#000000" stroke-width="0.011857142857142858" />
|
|
191
|
+
</g>
|
|
192
|
+
<g>
|
|
193
|
+
<rect data-type="rect" data-label="netId: GND
|
|
194
|
+
globalConnNetId: connectivity_net3" data-x="-2.7125000000000004" data-y="-1.2309999999999999" x="52.65060240963851" y="356.77108433734935" width="16.867469879518097" height="40.481927710843365" fill="#00000066" stroke="#000000" stroke-width="0.011857142857142858" />
|
|
195
|
+
</g>
|
|
196
|
+
<g>
|
|
197
|
+
<rect data-type="rect" data-label="netId: .J3 > .pin2 to .U1 > .pin7
|
|
198
|
+
globalConnNetId: connectivity_net2" data-x="-0.8350000000000001" data-y="-1.1649999999999998" x="210.99397590361446" y="352.4698795180723" width="16.86746987951807" height="37.95180722891564" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011857142857142858" />
|
|
199
|
+
</g>
|
|
200
|
+
<g>
|
|
201
|
+
<rect data-type="rect" data-label="netId: .J2 > .pin2 to .U1 > .pin10
|
|
202
|
+
globalConnNetId: connectivity_net1" data-x="-0.9975000000000006" data-y="0.09500000000000186" x="186.74698795180717" y="256.74698795180706" width="37.95180722891564" height="16.86746987951807" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011857142857142858" />
|
|
203
|
+
</g>
|
|
204
|
+
<g>
|
|
205
|
+
<rect data-type="rect" data-label="netId: .U1 > .VS2 to .U1 > .pin22
|
|
206
|
+
globalConnNetId: connectivity_net0" data-x="3.5774999999999997" data-y="1.2850000000000001" x="583.1325301204819" y="145.84337349397586" width="16.867469879518126" height="37.95180722891567" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011857142857142858" />
|
|
207
|
+
</g>
|
|
208
|
+
<g>
|
|
209
|
+
<rect data-type="rect" data-label="netId: VCC_3
|
|
210
|
+
globalConnNetId: connectivity_net4" data-x="-1.3235000000000006" data-y="1.2210000000000019" x="169.7951807228915" y="139.8554216867468" width="16.867469879518097" height="60.72289156626505" fill="#ef444466" stroke="#ef4444" stroke-width="0.011857142857142858" />
|
|
211
|
+
</g>
|
|
212
|
+
<g>
|
|
213
|
+
<rect data-type="rect" data-label="netId: VCC_3
|
|
214
|
+
globalConnNetId: connectivity_net4" data-x="-2.8625000000000003" data-y="-0.629" x="39.99999999999997" y="295.8795180722891" width="16.86746987951807" height="60.722891566265105" fill="#ef444466" stroke="#ef4444" stroke-width="0.011857142857142858" />
|
|
215
|
+
</g>
|
|
216
|
+
<g id="crosshair" style="display: none">
|
|
217
|
+
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
218
|
+
<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>
|
|
219
|
+
</g>
|
|
220
|
+
<script>
|
|
221
|
+
<![CDATA[
|
|
222
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
223
|
+
const svg = e.currentTarget;
|
|
224
|
+
const rect = svg.getBoundingClientRect();
|
|
225
|
+
const x = e.clientX - rect.left;
|
|
226
|
+
const y = e.clientY - rect.top;
|
|
227
|
+
const crosshair = svg.getElementById('crosshair');
|
|
228
|
+
const h = svg.getElementById('crosshair-h');
|
|
229
|
+
const v = svg.getElementById('crosshair-v');
|
|
230
|
+
const coords = svg.getElementById('coordinates');
|
|
231
|
+
|
|
232
|
+
crosshair.style.display = 'block';
|
|
233
|
+
h.setAttribute('x1', '0');
|
|
234
|
+
h.setAttribute('x2', '640');
|
|
235
|
+
h.setAttribute('y1', y);
|
|
236
|
+
h.setAttribute('y2', y);
|
|
237
|
+
v.setAttribute('x1', x);
|
|
238
|
+
v.setAttribute('x2', x);
|
|
239
|
+
v.setAttribute('y1', '0');
|
|
240
|
+
v.setAttribute('y2', '640');
|
|
241
|
+
|
|
242
|
+
// Calculate real coordinates using inverse transformation
|
|
243
|
+
const matrix = {
|
|
244
|
+
"a": 84.33734939759036,
|
|
245
|
+
"c": 0,
|
|
246
|
+
"e": 289.84939759036143,
|
|
247
|
+
"b": 0,
|
|
248
|
+
"d": -84.33734939759036,
|
|
249
|
+
"f": 273.1927710843373
|
|
250
|
+
};
|
|
251
|
+
// Manually invert and apply the affine transform
|
|
252
|
+
// Since we only use translate and scale, we can directly compute:
|
|
253
|
+
// x' = (x - tx) / sx
|
|
254
|
+
// y' = (y - ty) / sy
|
|
255
|
+
const sx = matrix.a;
|
|
256
|
+
const sy = matrix.d;
|
|
257
|
+
const tx = matrix.e;
|
|
258
|
+
const ty = matrix.f;
|
|
259
|
+
const realPoint = {
|
|
260
|
+
x: (x - tx) / sx,
|
|
261
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
265
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
266
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
267
|
+
});
|
|
268
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
269
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
270
|
+
});
|
|
271
|
+
]]>
|
|
272
|
+
</script>
|
|
273
|
+
</svg>
|
|
@@ -0,0 +1,113 @@
|
|
|
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.3
|
|
5
|
+
x+" data-x="1.7999999999999998" data-y="-0.975" cx="458.8517829187396" cy="381.2935323383084" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
|
|
6
|
+
</g>
|
|
7
|
+
<g>
|
|
8
|
+
<circle data-type="point" data-label="U1.4
|
|
9
|
+
x+" data-x="1.7999999999999998" data-y="-0.32499999999999996" cx="458.8517829187396" cy="320.9286898839137" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
|
|
10
|
+
</g>
|
|
11
|
+
<g>
|
|
12
|
+
<circle data-type="point" data-label="R1.2
|
|
13
|
+
y-" data-x="2.25" data-y="-0.9" cx="500.642827694859" cy="374.3283582089552" r="3" fill="hsl(227, 100%, 50%, 0.8)" />
|
|
14
|
+
</g>
|
|
15
|
+
<g>
|
|
16
|
+
<circle data-type="point" data-label="R2.2
|
|
17
|
+
y-" data-x="2.25" data-y="-2.6500000000000004" cx="500.642827694859" cy="536.849087893864" r="3" fill="hsl(108, 100%, 50%, 0.8)" />
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
<circle data-type="point" data-label="anchorPoint
|
|
21
|
+
orientation: y-" data-x="2.125" data-y="-2.8500000000000005" cx="489.034204145937" cy="555.4228855721392" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
22
|
+
</g>
|
|
23
|
+
<g>
|
|
24
|
+
<circle data-type="point" data-label="anchorPoint
|
|
25
|
+
orientation: y+" data-x="1.9249999999999998" data-y="-0.32499999999999996" cx="470.46040646766164" cy="320.9286898839137" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
<polyline data-points="1.7999999999999998,-0.32499999999999996 2.25,-0.9" data-type="line" data-label="" points="458.8517829187396,320.9286898839137 500.642827694859,374.3283582089552" fill="none" stroke="hsl(112, 100%, 50%, 0.8)" stroke-width="1" />
|
|
29
|
+
</g>
|
|
30
|
+
<g>
|
|
31
|
+
<polyline data-points="1.7999999999999998,-0.975 2.25,-2.6500000000000004" data-type="line" data-label="" points="458.8517829187396,381.2935323383084 500.642827694859,536.849087893864" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
32
|
+
</g>
|
|
33
|
+
<g>
|
|
34
|
+
<polyline data-points="1.7999999999999998,-0.32499999999999996 1.9249999999999998,-0.32499999999999996 1.9249999999999998,-1.1 2.25,-1.1 2.25,-0.9" data-type="line" data-label="" points="458.8517829187396,320.9286898839137 470.46040646766164,320.9286898839137 470.46040646766164,392.9021558872305 500.642827694859,392.9021558872305 500.642827694859,374.3283582089552" fill="none" stroke="purple" stroke-width="1" />
|
|
35
|
+
</g>
|
|
36
|
+
<g>
|
|
37
|
+
<polyline data-points="1.7999999999999998,-0.975 2.125,-0.975 2.125,-2.8500000000000005 2.25,-2.8500000000000005 2.25,-2.6500000000000004" data-type="line" data-label="" points="458.8517829187396,381.2935323383084 489.034204145937,381.2935323383084 489.034204145937,555.4228855721392 500.642827694859,555.4228855721392 500.642827694859,536.849087893864" fill="none" stroke="purple" stroke-width="1" />
|
|
38
|
+
</g>
|
|
39
|
+
<g>
|
|
40
|
+
<rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="124.52342470978448" y="40" width="334.32835820895514" height="501.49253731343276" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.010767857142857145" />
|
|
41
|
+
</g>
|
|
42
|
+
<g>
|
|
43
|
+
<rect data-type="rect" data-label="schematic_component_4" data-x="2.25" data-y="-0.35" x="485.8090800995025" y="272.1724709784411" width="29.667495190713055" height="102.15588723051411" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.010767857142857145" />
|
|
44
|
+
</g>
|
|
45
|
+
<g>
|
|
46
|
+
<rect data-type="rect" data-label="schematic_component_5" data-x="2.25" data-y="-2.1" x="485.8090800995025" y="434.6932006633499" width="29.667495190713055" height="102.15588723051405" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.010767857142857145" />
|
|
47
|
+
</g>
|
|
48
|
+
<g>
|
|
49
|
+
<rect data-type="rect" data-label="netId: GND
|
|
50
|
+
globalConnNetId: connectivity_net1" data-x="2.125" data-y="-3.0900000000000007" x="479.7473053067993" y="555.4228855721392" width="18.573797678275298" height="44.577114427860806" fill="#00000066" stroke="#000000" stroke-width="0.010767857142857145" />
|
|
51
|
+
</g>
|
|
52
|
+
<g>
|
|
53
|
+
<rect data-type="rect" data-label="netId: U1.FB to R1.pin2
|
|
54
|
+
globalConnNetId: connectivity_net0" data-x="1.9249999999999998" data-y="-0.09999999999999995" x="461.173507628524" y="279.1376451077943" width="18.573797678275298" height="41.791044776119406" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.010767857142857145" />
|
|
55
|
+
</g>
|
|
56
|
+
<g id="crosshair" style="display: none">
|
|
57
|
+
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
58
|
+
<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>
|
|
59
|
+
</g>
|
|
60
|
+
<script>
|
|
61
|
+
<![CDATA[
|
|
62
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
63
|
+
const svg = e.currentTarget;
|
|
64
|
+
const rect = svg.getBoundingClientRect();
|
|
65
|
+
const x = e.clientX - rect.left;
|
|
66
|
+
const y = e.clientY - rect.top;
|
|
67
|
+
const crosshair = svg.getElementById('crosshair');
|
|
68
|
+
const h = svg.getElementById('crosshair-h');
|
|
69
|
+
const v = svg.getElementById('crosshair-v');
|
|
70
|
+
const coords = svg.getElementById('coordinates');
|
|
71
|
+
|
|
72
|
+
crosshair.style.display = 'block';
|
|
73
|
+
h.setAttribute('x1', '0');
|
|
74
|
+
h.setAttribute('x2', '640');
|
|
75
|
+
h.setAttribute('y1', y);
|
|
76
|
+
h.setAttribute('y2', y);
|
|
77
|
+
v.setAttribute('x1', x);
|
|
78
|
+
v.setAttribute('x2', x);
|
|
79
|
+
v.setAttribute('y1', '0');
|
|
80
|
+
v.setAttribute('y2', '640');
|
|
81
|
+
|
|
82
|
+
// Calculate real coordinates using inverse transformation
|
|
83
|
+
const matrix = {
|
|
84
|
+
"a": 92.86898839137643,
|
|
85
|
+
"c": 0,
|
|
86
|
+
"e": 291.68760381426205,
|
|
87
|
+
"b": 0,
|
|
88
|
+
"d": -92.86898839137643,
|
|
89
|
+
"f": 290.7462686567164
|
|
90
|
+
};
|
|
91
|
+
// Manually invert and apply the affine transform
|
|
92
|
+
// Since we only use translate and scale, we can directly compute:
|
|
93
|
+
// x' = (x - tx) / sx
|
|
94
|
+
// y' = (y - ty) / sy
|
|
95
|
+
const sx = matrix.a;
|
|
96
|
+
const sy = matrix.d;
|
|
97
|
+
const tx = matrix.e;
|
|
98
|
+
const ty = matrix.f;
|
|
99
|
+
const realPoint = {
|
|
100
|
+
x: (x - tx) / sx,
|
|
101
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
105
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
106
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
107
|
+
});
|
|
108
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
109
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
110
|
+
});
|
|
111
|
+
]]>
|
|
112
|
+
</script>
|
|
113
|
+
</svg>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "schematic_component_0",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": 1.8774999999999997,
|
|
7
|
+
"y": -0.43999999999999995
|
|
8
|
+
},
|
|
9
|
+
"width": 2.2,
|
|
10
|
+
"height": 5.2,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "U1.3",
|
|
14
|
+
"x": 3.3774999999999995,
|
|
15
|
+
"y": -2.7900000000000005
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pinId": "U1.7",
|
|
19
|
+
"x": 0.3774999999999997,
|
|
20
|
+
"y": -1.39
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"pinId": "U1.10",
|
|
24
|
+
"x": 0.3774999999999997,
|
|
25
|
+
"y": 0.3100000000000005
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"pinId": "U1.13",
|
|
29
|
+
"x": 0.3774999999999997,
|
|
30
|
+
"y": -0.1899999999999995
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"pinId": "U1.18",
|
|
34
|
+
"x": 3.3774999999999995,
|
|
35
|
+
"y": -2.5900000000000003
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"pinId": "U1.22",
|
|
39
|
+
"x": 3.3774999999999995,
|
|
40
|
+
"y": 1.7100000000000004
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"pinId": "U1.28",
|
|
44
|
+
"x": 3.3774999999999995,
|
|
45
|
+
"y": 1.5100000000000002
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"pinId": "U1.29",
|
|
49
|
+
"x": 3.3774999999999995,
|
|
50
|
+
"y": -2.3900000000000006
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"chipId": "schematic_component_6",
|
|
56
|
+
"center": {
|
|
57
|
+
"x": -0.7725000000000006,
|
|
58
|
+
"y": 0.5600000000000018
|
|
59
|
+
},
|
|
60
|
+
"width": 0.9,
|
|
61
|
+
"height": 0.53,
|
|
62
|
+
"pins": [
|
|
63
|
+
{
|
|
64
|
+
"pinId": "J2.1",
|
|
65
|
+
"x": -1.2225000000000006,
|
|
66
|
+
"y": 0.6600000000000018
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"pinId": "J2.2",
|
|
70
|
+
"x": -0.7725000000000006,
|
|
71
|
+
"y": 0.31000000000000183
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"pinId": "J2.3",
|
|
75
|
+
"x": -0.3225000000000006,
|
|
76
|
+
"y": 0.6600000000000018
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"chipId": "schematic_component_7",
|
|
82
|
+
"center": {
|
|
83
|
+
"x": -2.3125,
|
|
84
|
+
"y": -1.39
|
|
85
|
+
},
|
|
86
|
+
"width": 0.53,
|
|
87
|
+
"height": 0.9,
|
|
88
|
+
"pins": [
|
|
89
|
+
{
|
|
90
|
+
"pinId": "J3.1",
|
|
91
|
+
"x": -2.4125,
|
|
92
|
+
"y": -1.84
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"pinId": "J3.2",
|
|
96
|
+
"x": -2.0625,
|
|
97
|
+
"y": -1.39
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"pinId": "J3.3",
|
|
101
|
+
"x": -2.4125,
|
|
102
|
+
"y": -0.94
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"directConnections": [
|
|
108
|
+
{
|
|
109
|
+
"pinIds": ["U1.28", "U1.22"],
|
|
110
|
+
"netId": ".U1 > .VS2 to .U1 > .pin22"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"pinIds": ["J2.2", "U1.10"],
|
|
114
|
+
"netId": ".J2 > .pin2 to .U1 > .pin10"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"pinIds": ["J3.2", "U1.7"],
|
|
118
|
+
"netId": ".J3 > .pin2 to .U1 > .pin7"
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"netConnections": [
|
|
122
|
+
{
|
|
123
|
+
"netId": "GND",
|
|
124
|
+
"pinIds": ["U1.3", "U1.13", "U1.18", "U1.29", "J2.3", "J3.3"],
|
|
125
|
+
"netLabelWidth": 0.48
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"netId": "VCC_3",
|
|
129
|
+
"pinIds": ["J2.1", "J3.1"],
|
|
130
|
+
"netLabelWidth": 0.72
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"availableNetLabelOrientations": {
|
|
134
|
+
"GND": ["y-"],
|
|
135
|
+
"VCC_5": ["y+"],
|
|
136
|
+
"VCC_3": ["y+"]
|
|
137
|
+
},
|
|
138
|
+
"maxMspPairDistance": 2.4
|
|
139
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "schematic_component_0",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": 0,
|
|
7
|
+
"y": 0
|
|
8
|
+
},
|
|
9
|
+
"width": 2.8,
|
|
10
|
+
"height": 5.4,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "U1.3",
|
|
14
|
+
"x": 1.7999999999999998,
|
|
15
|
+
"y": -0.975
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pinId": "U1.4",
|
|
19
|
+
"x": 1.7999999999999998,
|
|
20
|
+
"y": -0.32499999999999996
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"chipId": "schematic_component_4",
|
|
26
|
+
"center": {
|
|
27
|
+
"x": 2.25,
|
|
28
|
+
"y": -0.35
|
|
29
|
+
},
|
|
30
|
+
"width": 0.3194553499999995,
|
|
31
|
+
"height": 1.1,
|
|
32
|
+
"pins": [
|
|
33
|
+
{
|
|
34
|
+
"pinId": "R1.2",
|
|
35
|
+
"x": 2.25,
|
|
36
|
+
"y": -0.8999999999999999
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"chipId": "schematic_component_5",
|
|
42
|
+
"center": {
|
|
43
|
+
"x": 2.25,
|
|
44
|
+
"y": -2.1
|
|
45
|
+
},
|
|
46
|
+
"width": 0.3194553499999995,
|
|
47
|
+
"height": 1.1,
|
|
48
|
+
"pins": [
|
|
49
|
+
{
|
|
50
|
+
"pinId": "R2.2",
|
|
51
|
+
"x": 2.25,
|
|
52
|
+
"y": -2.65
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"directConnections": [
|
|
58
|
+
{
|
|
59
|
+
"pinIds": ["U1.4", "R1.2"],
|
|
60
|
+
"netId": "U1.FB to R1.pin2"
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"netConnections": [
|
|
64
|
+
{
|
|
65
|
+
"netId": "GND",
|
|
66
|
+
"pinIds": ["U1.3", "R2.2"],
|
|
67
|
+
"netLabelWidth": 0.48
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"availableNetLabelOrientations": {
|
|
71
|
+
"GND": ["y-"]
|
|
72
|
+
},
|
|
73
|
+
"maxMspPairDistance": 2.4
|
|
74
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { test, expect } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import ip from "./assets/repro-netlabel-connector-through-label.input.json"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
import { getTraceLabelCollisions } from "tests/fixtures/traceLabelCollisions"
|
|
6
|
+
|
|
7
|
+
test("netlabel connector trace should not pass through a rail label", () => {
|
|
8
|
+
const solver = new SchematicTracePipelineSolver(ip as any)
|
|
9
|
+
solver.solve()
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
getTraceLabelCollisions(
|
|
13
|
+
solver.netLabelNetLabelCollisionSolver!.traces,
|
|
14
|
+
solver.netLabelNetLabelCollisionSolver!.outputNetLabelPlacements,
|
|
15
|
+
),
|
|
16
|
+
).toEqual([])
|
|
17
|
+
|
|
18
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
19
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import inputProblem from "./assets/repro126-trace-overlap-box-resistor.input.json"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
|
|
6
|
+
test("repro126 trace overlaps R2 box", () => {
|
|
7
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
|
+
solver.solve()
|
|
9
|
+
|
|
10
|
+
expect(
|
|
11
|
+
solver.traceOverlapShiftSolver!.correctedTraceMap["U1.3-R2.2"],
|
|
12
|
+
).toBeDefined()
|
|
13
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
14
|
+
})
|