@tscircuit/schematic-trace-solver 0.0.79 → 0.0.81
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 +6 -1
- package/dist/index.js +77 -28
- package/lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts +64 -4
- package/lib/solvers/AvailableNetOrientationSolver/types.ts +1 -0
- package/lib/solvers/Example28Solver/getMovedAnchorPointForReroute.ts +37 -0
- package/lib/solvers/Example28Solver/isLabelAttachedToTrace.ts +9 -0
- package/lib/solvers/Example28Solver/labelMovement.ts +2 -43
- package/package.json +1 -1
- package/tests/examples/__snapshots__/example46.snap.svg +4 -4
- package/tests/repros/__snapshots__/bugreport-001-gnd-overlap.snap.svg +219 -0
- package/tests/repros/assets/bugreport-001-gnd-overlap.input.json +163 -0
- package/tests/repros/bugreport-001-gnd-overlap.test.ts +16 -0
package/dist/index.d.ts
CHANGED
|
@@ -694,7 +694,7 @@ type CandidateLabel = {
|
|
|
694
694
|
width: number;
|
|
695
695
|
height: number;
|
|
696
696
|
};
|
|
697
|
-
type CandidateStatus$2 = "valid" | "chip-collision" | "text-collision" | "trace-collision" | "netlabel-collision";
|
|
697
|
+
type CandidateStatus$2 = "valid" | "chip-collision" | "text-collision" | "trace-collision" | "trace-clearance-violation" | "netlabel-collision";
|
|
698
698
|
type CandidatePhase = "rotate" | "shift" | "lateral-shift";
|
|
699
699
|
type EvaluatedCandidate = CandidateLabel & {
|
|
700
700
|
status: CandidateStatus$2;
|
|
@@ -758,6 +758,11 @@ declare class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
758
758
|
private getNetLabelHeight;
|
|
759
759
|
private getCandidateStatus;
|
|
760
760
|
private getBoundsStatus;
|
|
761
|
+
private isTraceTooCloseToLabel;
|
|
762
|
+
private getLabelTraceClearanceBounds;
|
|
763
|
+
private shouldCheckTraceClearanceForLabel;
|
|
764
|
+
private hasRoutedLabelOnSameNet;
|
|
765
|
+
private isPortOnlyLabel;
|
|
761
766
|
private intersectsAnyOtherNetLabel;
|
|
762
767
|
private sharesChipBoundary;
|
|
763
768
|
private getChipSideForPoint;
|
package/dist/index.js
CHANGED
|
@@ -5314,6 +5314,33 @@ var segmentRunsAlongRectBoundary = (start, end, rect) => {
|
|
|
5314
5314
|
return false;
|
|
5315
5315
|
};
|
|
5316
5316
|
|
|
5317
|
+
// lib/solvers/Example28Solver/getMovedAnchorPointForReroute.ts
|
|
5318
|
+
var getMovedAnchorPointForReroute = (anchorPoint, originalTracePath, reroutedTracePath) => {
|
|
5319
|
+
const originalSegment = findSegmentContainingPoint(
|
|
5320
|
+
originalTracePath,
|
|
5321
|
+
anchorPoint
|
|
5322
|
+
);
|
|
5323
|
+
if (!originalSegment) return null;
|
|
5324
|
+
const preferredSegment = findPreferredReroutedSegment(
|
|
5325
|
+
reroutedTracePath,
|
|
5326
|
+
originalSegment.index,
|
|
5327
|
+
originalTracePath.length - 1,
|
|
5328
|
+
originalSegment.orientation,
|
|
5329
|
+
anchorPoint
|
|
5330
|
+
);
|
|
5331
|
+
if (!preferredSegment) {
|
|
5332
|
+
return projectPointToPath(anchorPoint, reroutedTracePath);
|
|
5333
|
+
}
|
|
5334
|
+
return projectPointToSegment(
|
|
5335
|
+
anchorPoint,
|
|
5336
|
+
preferredSegment.start,
|
|
5337
|
+
preferredSegment.end
|
|
5338
|
+
);
|
|
5339
|
+
};
|
|
5340
|
+
|
|
5341
|
+
// lib/solvers/Example28Solver/isLabelAttachedToTrace.ts
|
|
5342
|
+
var isLabelAttachedToTrace = (label, trace) => label.globalConnNetId === trace.globalConnNetId || label.mspConnectionPairIds.includes(trace.mspPairId);
|
|
5343
|
+
|
|
5317
5344
|
// lib/solvers/Example28Solver/labelMovement.ts
|
|
5318
5345
|
var moveAttachedLabelsToReroutedTrace = ({
|
|
5319
5346
|
trace,
|
|
@@ -5341,29 +5368,6 @@ var moveAttachedLabelsToReroutedTrace = ({
|
|
|
5341
5368
|
}
|
|
5342
5369
|
};
|
|
5343
5370
|
});
|
|
5344
|
-
var isLabelAttachedToTrace = (label, trace) => label.globalConnNetId === trace.globalConnNetId || label.mspConnectionPairIds.includes(trace.mspPairId);
|
|
5345
|
-
var getMovedAnchorPointForReroute = (anchorPoint, originalTracePath, reroutedTracePath) => {
|
|
5346
|
-
const originalSegment = findSegmentContainingPoint(
|
|
5347
|
-
originalTracePath,
|
|
5348
|
-
anchorPoint
|
|
5349
|
-
);
|
|
5350
|
-
if (!originalSegment) return null;
|
|
5351
|
-
const preferredSegment = findPreferredReroutedSegment(
|
|
5352
|
-
reroutedTracePath,
|
|
5353
|
-
originalSegment.index,
|
|
5354
|
-
originalTracePath.length - 1,
|
|
5355
|
-
originalSegment.orientation,
|
|
5356
|
-
anchorPoint
|
|
5357
|
-
);
|
|
5358
|
-
if (!preferredSegment) {
|
|
5359
|
-
return projectPointToPath(anchorPoint, reroutedTracePath);
|
|
5360
|
-
}
|
|
5361
|
-
return projectPointToSegment(
|
|
5362
|
-
anchorPoint,
|
|
5363
|
-
preferredSegment.start,
|
|
5364
|
-
preferredSegment.end
|
|
5365
|
-
);
|
|
5366
|
-
};
|
|
5367
5371
|
|
|
5368
5372
|
// lib/utils/dir.ts
|
|
5369
5373
|
var dir = (facingDirection) => {
|
|
@@ -6163,6 +6167,7 @@ var ensureGraphicsArrays = (graphics) => {
|
|
|
6163
6167
|
};
|
|
6164
6168
|
|
|
6165
6169
|
// lib/solvers/AvailableNetOrientationSolver/AvailableNetOrientationSolver.ts
|
|
6170
|
+
var LABEL_TRACE_CLEARANCE = 0.1;
|
|
6166
6171
|
var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
6167
6172
|
inputProblem;
|
|
6168
6173
|
traces;
|
|
@@ -6576,10 +6581,15 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
6576
6581
|
}
|
|
6577
6582
|
getCandidateStatus(params) {
|
|
6578
6583
|
const { candidate, label, labelIndex, phase } = params;
|
|
6579
|
-
const boundsStatus = this.getBoundsStatus(
|
|
6580
|
-
getRectBounds(
|
|
6581
|
-
|
|
6582
|
-
|
|
6584
|
+
const boundsStatus = this.getBoundsStatus({
|
|
6585
|
+
bounds: getRectBounds(
|
|
6586
|
+
candidate.center,
|
|
6587
|
+
candidate.width,
|
|
6588
|
+
candidate.height
|
|
6589
|
+
),
|
|
6590
|
+
labelIndex,
|
|
6591
|
+
label
|
|
6592
|
+
});
|
|
6583
6593
|
if (boundsStatus !== "valid") return boundsStatus;
|
|
6584
6594
|
const connectorTrace = this.getCandidateConnectorTrace(label, {
|
|
6585
6595
|
anchorPoint: candidate.anchorPoint,
|
|
@@ -6603,7 +6613,8 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
6603
6613
|
}
|
|
6604
6614
|
return "valid";
|
|
6605
6615
|
}
|
|
6606
|
-
getBoundsStatus(
|
|
6616
|
+
getBoundsStatus(candidateBoundsCheck) {
|
|
6617
|
+
const { bounds, labelIndex, label } = candidateBoundsCheck;
|
|
6607
6618
|
if (this.chipObstacleSpatialIndex.getChipsInBounds(bounds).length > 0) {
|
|
6608
6619
|
return "chip-collision";
|
|
6609
6620
|
}
|
|
@@ -6616,11 +6627,49 @@ var AvailableNetOrientationSolver = class extends BaseSolver {
|
|
|
6616
6627
|
if (traceCrossesBoundsInterior(bounds, this.traceMap)) {
|
|
6617
6628
|
return "trace-collision";
|
|
6618
6629
|
}
|
|
6630
|
+
if (this.isTraceTooCloseToLabel(bounds, label)) {
|
|
6631
|
+
return "trace-clearance-violation";
|
|
6632
|
+
}
|
|
6619
6633
|
if (this.intersectsAnyOtherNetLabel(bounds, labelIndex)) {
|
|
6620
6634
|
return "netlabel-collision";
|
|
6621
6635
|
}
|
|
6622
6636
|
return "valid";
|
|
6623
6637
|
}
|
|
6638
|
+
isTraceTooCloseToLabel(bounds, label) {
|
|
6639
|
+
if (!this.shouldCheckTraceClearanceForLabel(label)) return false;
|
|
6640
|
+
const clearanceBounds = this.getLabelTraceClearanceBounds(bounds);
|
|
6641
|
+
for (const trace of Object.values(this.traceMap)) {
|
|
6642
|
+
if (trace.globalConnNetId === label.globalConnNetId) continue;
|
|
6643
|
+
if (tracePathIntersectsBounds(trace.tracePath, clearanceBounds)) {
|
|
6644
|
+
return true;
|
|
6645
|
+
}
|
|
6646
|
+
}
|
|
6647
|
+
return false;
|
|
6648
|
+
}
|
|
6649
|
+
getLabelTraceClearanceBounds(bounds) {
|
|
6650
|
+
return {
|
|
6651
|
+
minX: bounds.minX - LABEL_TRACE_CLEARANCE,
|
|
6652
|
+
minY: bounds.minY - LABEL_TRACE_CLEARANCE,
|
|
6653
|
+
maxX: bounds.maxX + LABEL_TRACE_CLEARANCE,
|
|
6654
|
+
maxY: bounds.maxY + LABEL_TRACE_CLEARANCE
|
|
6655
|
+
};
|
|
6656
|
+
}
|
|
6657
|
+
shouldCheckTraceClearanceForLabel(label) {
|
|
6658
|
+
if (!this.isPortOnlyLabel(label)) return false;
|
|
6659
|
+
if (!this.hasRoutedLabelOnSameNet(label)) return false;
|
|
6660
|
+
const orientations = this.getAvailableOrientations(label);
|
|
6661
|
+
return orientations.length === 1;
|
|
6662
|
+
}
|
|
6663
|
+
hasRoutedLabelOnSameNet(label) {
|
|
6664
|
+
for (const otherLabel of this.outputNetLabelPlacements) {
|
|
6665
|
+
if (otherLabel.globalConnNetId !== label.globalConnNetId) continue;
|
|
6666
|
+
if (otherLabel.mspConnectionPairIds.length > 0) return true;
|
|
6667
|
+
}
|
|
6668
|
+
return false;
|
|
6669
|
+
}
|
|
6670
|
+
isPortOnlyLabel(label) {
|
|
6671
|
+
return label.mspConnectionPairIds.length === 0;
|
|
6672
|
+
}
|
|
6624
6673
|
intersectsAnyOtherNetLabel(bounds, labelIndex) {
|
|
6625
6674
|
for (let i = 0; i < this.outputNetLabelPlacements.length; i++) {
|
|
6626
6675
|
if (i === labelIndex) continue;
|
|
@@ -38,6 +38,8 @@ import type {
|
|
|
38
38
|
import { visualizeAvailableNetOrientationSolver } from "./visualize"
|
|
39
39
|
import { rectIntersectsAnyTextBox } from "lib/utils/textBoxBounds"
|
|
40
40
|
|
|
41
|
+
const LABEL_TRACE_CLEARANCE = 0.1
|
|
42
|
+
|
|
41
43
|
export class AvailableNetOrientationSolver extends BaseSolver {
|
|
42
44
|
inputProblem: InputProblem
|
|
43
45
|
traces: SolvedTracePath[]
|
|
@@ -606,10 +608,15 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
606
608
|
phase: CandidatePhase
|
|
607
609
|
}) {
|
|
608
610
|
const { candidate, label, labelIndex, phase } = params
|
|
609
|
-
const boundsStatus = this.getBoundsStatus(
|
|
610
|
-
getRectBounds(
|
|
611
|
+
const boundsStatus = this.getBoundsStatus({
|
|
612
|
+
bounds: getRectBounds(
|
|
613
|
+
candidate.center,
|
|
614
|
+
candidate.width,
|
|
615
|
+
candidate.height,
|
|
616
|
+
),
|
|
611
617
|
labelIndex,
|
|
612
|
-
|
|
618
|
+
label,
|
|
619
|
+
})
|
|
613
620
|
if (boundsStatus !== "valid") return boundsStatus
|
|
614
621
|
|
|
615
622
|
const connectorTrace = this.getCandidateConnectorTrace(label, {
|
|
@@ -640,7 +647,13 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
640
647
|
return "valid"
|
|
641
648
|
}
|
|
642
649
|
|
|
643
|
-
private getBoundsStatus(
|
|
650
|
+
private getBoundsStatus(candidateBoundsCheck: {
|
|
651
|
+
bounds: Bounds
|
|
652
|
+
labelIndex: number
|
|
653
|
+
label: NetLabelPlacement
|
|
654
|
+
}): CandidateStatus {
|
|
655
|
+
const { bounds, labelIndex, label } = candidateBoundsCheck
|
|
656
|
+
|
|
644
657
|
if (this.chipObstacleSpatialIndex.getChipsInBounds(bounds).length > 0) {
|
|
645
658
|
return "chip-collision"
|
|
646
659
|
}
|
|
@@ -653,12 +666,59 @@ export class AvailableNetOrientationSolver extends BaseSolver {
|
|
|
653
666
|
if (traceCrossesBoundsInterior(bounds, this.traceMap)) {
|
|
654
667
|
return "trace-collision"
|
|
655
668
|
}
|
|
669
|
+
if (this.isTraceTooCloseToLabel(bounds, label)) {
|
|
670
|
+
return "trace-clearance-violation"
|
|
671
|
+
}
|
|
656
672
|
if (this.intersectsAnyOtherNetLabel(bounds, labelIndex)) {
|
|
657
673
|
return "netlabel-collision"
|
|
658
674
|
}
|
|
659
675
|
return "valid"
|
|
660
676
|
}
|
|
661
677
|
|
|
678
|
+
private isTraceTooCloseToLabel(bounds: Bounds, label: NetLabelPlacement) {
|
|
679
|
+
if (!this.shouldCheckTraceClearanceForLabel(label)) return false
|
|
680
|
+
|
|
681
|
+
const clearanceBounds = this.getLabelTraceClearanceBounds(bounds)
|
|
682
|
+
for (const trace of Object.values(this.traceMap)) {
|
|
683
|
+
if (trace.globalConnNetId === label.globalConnNetId) continue
|
|
684
|
+
if (tracePathIntersectsBounds(trace.tracePath, clearanceBounds)) {
|
|
685
|
+
return true
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return false
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
private getLabelTraceClearanceBounds(bounds: Bounds): Bounds {
|
|
693
|
+
return {
|
|
694
|
+
minX: bounds.minX - LABEL_TRACE_CLEARANCE,
|
|
695
|
+
minY: bounds.minY - LABEL_TRACE_CLEARANCE,
|
|
696
|
+
maxX: bounds.maxX + LABEL_TRACE_CLEARANCE,
|
|
697
|
+
maxY: bounds.maxY + LABEL_TRACE_CLEARANCE,
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
private shouldCheckTraceClearanceForLabel(label: NetLabelPlacement) {
|
|
702
|
+
if (!this.isPortOnlyLabel(label)) return false
|
|
703
|
+
if (!this.hasRoutedLabelOnSameNet(label)) return false
|
|
704
|
+
|
|
705
|
+
const orientations = this.getAvailableOrientations(label)
|
|
706
|
+
return orientations.length === 1
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
private hasRoutedLabelOnSameNet(label: NetLabelPlacement) {
|
|
710
|
+
for (const otherLabel of this.outputNetLabelPlacements) {
|
|
711
|
+
if (otherLabel.globalConnNetId !== label.globalConnNetId) continue
|
|
712
|
+
if (otherLabel.mspConnectionPairIds.length > 0) return true
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return false
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
private isPortOnlyLabel(label: NetLabelPlacement) {
|
|
719
|
+
return label.mspConnectionPairIds.length === 0
|
|
720
|
+
}
|
|
721
|
+
|
|
662
722
|
private intersectsAnyOtherNetLabel(bounds: Bounds, labelIndex: number) {
|
|
663
723
|
for (let i = 0; i < this.outputNetLabelPlacements.length; i++) {
|
|
664
724
|
if (i === labelIndex) continue
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Point } from "@tscircuit/math-utils"
|
|
2
|
+
import {
|
|
3
|
+
findPreferredReroutedSegment,
|
|
4
|
+
findSegmentContainingPoint,
|
|
5
|
+
projectPointToPath,
|
|
6
|
+
projectPointToSegment,
|
|
7
|
+
} from "./geometry"
|
|
8
|
+
|
|
9
|
+
export const getMovedAnchorPointForReroute = (
|
|
10
|
+
anchorPoint: Point,
|
|
11
|
+
originalTracePath: Point[],
|
|
12
|
+
reroutedTracePath: Point[],
|
|
13
|
+
) => {
|
|
14
|
+
const originalSegment = findSegmentContainingPoint(
|
|
15
|
+
originalTracePath,
|
|
16
|
+
anchorPoint,
|
|
17
|
+
)
|
|
18
|
+
if (!originalSegment) return null
|
|
19
|
+
|
|
20
|
+
const preferredSegment = findPreferredReroutedSegment(
|
|
21
|
+
reroutedTracePath,
|
|
22
|
+
originalSegment.index,
|
|
23
|
+
originalTracePath.length - 1,
|
|
24
|
+
originalSegment.orientation,
|
|
25
|
+
anchorPoint,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if (!preferredSegment) {
|
|
29
|
+
return projectPointToPath(anchorPoint, reroutedTracePath)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return projectPointToSegment(
|
|
33
|
+
anchorPoint,
|
|
34
|
+
preferredSegment.start,
|
|
35
|
+
preferredSegment.end,
|
|
36
|
+
)
|
|
37
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
2
|
+
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
3
|
+
|
|
4
|
+
export const isLabelAttachedToTrace = (
|
|
5
|
+
label: NetLabelPlacement,
|
|
6
|
+
trace: SolvedTracePath,
|
|
7
|
+
) =>
|
|
8
|
+
label.globalConnNetId === trace.globalConnNetId ||
|
|
9
|
+
label.mspConnectionPairIds.includes(trace.mspPairId)
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { Point } from "@tscircuit/math-utils"
|
|
2
2
|
import type { NetLabelPlacement } from "lib/solvers/NetLabelPlacementSolver/NetLabelPlacementSolver"
|
|
3
3
|
import type { SolvedTracePath } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceLinesSolver"
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
findSegmentContainingPoint,
|
|
7
|
-
projectPointToPath,
|
|
8
|
-
projectPointToSegment,
|
|
9
|
-
} from "./geometry"
|
|
4
|
+
import { getMovedAnchorPointForReroute } from "./getMovedAnchorPointForReroute"
|
|
5
|
+
import { isLabelAttachedToTrace } from "./isLabelAttachedToTrace"
|
|
10
6
|
|
|
11
7
|
export const moveAttachedLabelsToReroutedTrace = ({
|
|
12
8
|
trace,
|
|
@@ -43,40 +39,3 @@ export const moveAttachedLabelsToReroutedTrace = ({
|
|
|
43
39
|
},
|
|
44
40
|
}
|
|
45
41
|
})
|
|
46
|
-
|
|
47
|
-
const isLabelAttachedToTrace = (
|
|
48
|
-
label: NetLabelPlacement,
|
|
49
|
-
trace: SolvedTracePath,
|
|
50
|
-
) =>
|
|
51
|
-
label.globalConnNetId === trace.globalConnNetId ||
|
|
52
|
-
label.mspConnectionPairIds.includes(trace.mspPairId)
|
|
53
|
-
|
|
54
|
-
const getMovedAnchorPointForReroute = (
|
|
55
|
-
anchorPoint: Point,
|
|
56
|
-
originalTracePath: Point[],
|
|
57
|
-
reroutedTracePath: Point[],
|
|
58
|
-
) => {
|
|
59
|
-
const originalSegment = findSegmentContainingPoint(
|
|
60
|
-
originalTracePath,
|
|
61
|
-
anchorPoint,
|
|
62
|
-
)
|
|
63
|
-
if (!originalSegment) return null
|
|
64
|
-
|
|
65
|
-
const preferredSegment = findPreferredReroutedSegment(
|
|
66
|
-
reroutedTracePath,
|
|
67
|
-
originalSegment.index,
|
|
68
|
-
originalTracePath.length - 1,
|
|
69
|
-
originalSegment.orientation,
|
|
70
|
-
anchorPoint,
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
if (!preferredSegment) {
|
|
74
|
-
return projectPointToPath(anchorPoint, reroutedTracePath)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return projectPointToSegment(
|
|
78
|
-
anchorPoint,
|
|
79
|
-
preferredSegment.start,
|
|
80
|
-
preferredSegment.end,
|
|
81
|
-
)
|
|
82
|
-
}
|
package/package.json
CHANGED
|
@@ -86,7 +86,7 @@ orientation: x-" data-x="-1.485" data-y="-0.2" cx="256.11911623439005" cy="288.2
|
|
|
86
86
|
</g>
|
|
87
87
|
<g>
|
|
88
88
|
<circle data-type="point" data-label="anchorPoint
|
|
89
|
-
orientation: y-" data-x="-1.3860000000000001" data-y="-0.
|
|
89
|
+
orientation: y-" data-x="-1.3860000000000001" data-y="-0.601" cx="261.4447646493756" cy="309.8328530259365" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
90
90
|
</g>
|
|
91
91
|
<g>
|
|
92
92
|
<circle data-type="point" data-label="anchorPoint
|
|
@@ -218,10 +218,10 @@ orientation: x-" data-x="2.6749999999999994" data-y="-2.7362499999999996" cx="47
|
|
|
218
218
|
<polyline data-points="-1.2850000000000001,0.20000000000000018 -1.866,0.20000000000000018 -1.866,-4.440892098500626e-16 -2.87,-4.440892098500626e-16 -2.87,0.19999999999999973" data-type="line" data-label="" points="266.8780019212296,266.74351585014404 235.62343900096062,266.74351585014404 235.62343900096062,277.5024015369836 181.61383285302594,277.5024015369836 181.61383285302594,266.74351585014404" fill="none" stroke="purple" stroke-width="1" />
|
|
219
219
|
</g>
|
|
220
220
|
<g>
|
|
221
|
-
<polyline data-points="-1.2850000000000001,-0.2 -1.485,-0.2 -1.485,-0.
|
|
221
|
+
<polyline data-points="-1.2850000000000001,-0.2 -1.485,-0.2 -1.485,-0.5 -2.166,-0.5 -2.166,0.5 -1.485,0.5 -1.485,0.2 -1.2850000000000001,0.2" data-type="line" data-label="" points="266.8780019212296,288.26128722382316 256.11911623439005,288.26128722382316 256.11911623439005,304.39961575408256 219.48511047070127,304.39961575408256 219.48511047070127,250.60518731988466 256.11911623439005,250.60518731988466 256.11911623439005,266.74351585014404 266.8780019212296,266.74351585014404" fill="none" stroke="purple" stroke-width="1" />
|
|
222
222
|
</g>
|
|
223
223
|
<g>
|
|
224
|
-
<polyline data-points="-1.2850000000000001,0 -1.3860000000000001,0 -1.3860000000000001,-0.
|
|
224
|
+
<polyline data-points="-1.2850000000000001,0 -1.3860000000000001,0 -1.3860000000000001,-0.601" data-type="line" data-label="" points="266.8780019212296,277.5024015369836 261.4447646493756,277.5024015369836 261.4447646493756,309.8328530259365" fill="none" stroke="purple" stroke-width="1" />
|
|
225
225
|
</g>
|
|
226
226
|
<g>
|
|
227
227
|
<rect data-type="rect" data-label="schematic_component_0" data-x="-2.71" data-y="0.7199999999999998" x="167.08933717579254" y="210.79731027857824" width="46.26320845341016" height="55.9462055715658" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018589285714285714" />
|
|
@@ -257,7 +257,7 @@ globalConnNetId: connectivity_net1" data-x="-1.725" data-y="-0.2" x="230.2977905
|
|
|
257
257
|
</g>
|
|
258
258
|
<g>
|
|
259
259
|
<rect data-type="rect" data-label="netId: GND
|
|
260
|
-
globalConnNetId: connectivity_net2" data-x="-1.3860000000000001" data-y="-0.
|
|
260
|
+
globalConnNetId: connectivity_net2" data-x="-1.3860000000000001" data-y="-0.841" x="256.0653218059558" y="309.8328530259365" width="10.758885686839562" height="25.821325648414984" fill="#00000066" stroke="#000000" stroke-width="0.018589285714285714" />
|
|
261
261
|
</g>
|
|
262
262
|
<g>
|
|
263
263
|
<rect data-type="rect" data-label="netId: GND
|
|
@@ -0,0 +1,219 @@
|
|
|
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="BT1.1
|
|
5
|
+
x+" data-x="-2.6" data-y="2.2" cx="84.13793103448276" cy="230.89655172413794" r="3" fill="hsl(114, 100%, 50%, 0.8)" />
|
|
6
|
+
</g>
|
|
7
|
+
<g>
|
|
8
|
+
<circle data-type="point" data-label="BT1.2
|
|
9
|
+
x+" data-x="-2.6" data-y="1.8" cx="84.13793103448276" cy="252.9655172413793" r="3" fill="hsl(115, 100%, 50%, 0.8)" />
|
|
10
|
+
</g>
|
|
11
|
+
<g>
|
|
12
|
+
<circle data-type="point" data-label="SW1.1
|
|
13
|
+
x-" data-x="-0.5" data-y="2" cx="200" cy="241.93103448275863" r="3" fill="hsl(104, 100%, 50%, 0.8)" />
|
|
14
|
+
</g>
|
|
15
|
+
<g>
|
|
16
|
+
<circle data-type="point" data-label="SW1.2
|
|
17
|
+
x+" data-x="0.5" data-y="2" cx="255.17241379310343" cy="241.93103448275863" r="3" fill="hsl(105, 100%, 50%, 0.8)" />
|
|
18
|
+
</g>
|
|
19
|
+
<g>
|
|
20
|
+
<circle data-type="point" data-label="R1.1
|
|
21
|
+
x-" data-x="2.45" data-y="1" cx="362.7586206896552" cy="297.1034482758621" r="3" fill="hsl(226, 100%, 50%, 0.8)" />
|
|
22
|
+
</g>
|
|
23
|
+
<g>
|
|
24
|
+
<circle data-type="point" data-label="R1.2
|
|
25
|
+
x+" data-x="3.55" data-y="1" cx="423.44827586206895" cy="297.1034482758621" r="3" fill="hsl(227, 100%, 50%, 0.8)" />
|
|
26
|
+
</g>
|
|
27
|
+
<g>
|
|
28
|
+
<circle data-type="point" data-label="R2.1
|
|
29
|
+
x-" data-x="2.45" data-y="-1" cx="362.7586206896552" cy="407.44827586206895" r="3" fill="hsl(107, 100%, 50%, 0.8)" />
|
|
30
|
+
</g>
|
|
31
|
+
<g>
|
|
32
|
+
<circle data-type="point" data-label="R2.2
|
|
33
|
+
x+" data-x="3.55" data-y="-1" cx="423.44827586206895" cy="407.44827586206895" r="3" fill="hsl(108, 100%, 50%, 0.8)" />
|
|
34
|
+
</g>
|
|
35
|
+
<g>
|
|
36
|
+
<circle data-type="point" data-label="D1.1
|
|
37
|
+
x-" data-x="5.45" data-y="1" cx="528.2758620689655" cy="297.1034482758621" r="3" fill="hsl(32, 100%, 50%, 0.8)" />
|
|
38
|
+
</g>
|
|
39
|
+
<g>
|
|
40
|
+
<circle data-type="point" data-label="D1.2
|
|
41
|
+
x+" data-x="6.55" data-y="1" cx="588.9655172413793" cy="297.1034482758621" r="3" fill="hsl(33, 100%, 50%, 0.8)" />
|
|
42
|
+
</g>
|
|
43
|
+
<g>
|
|
44
|
+
<circle data-type="point" data-label="D2.1
|
|
45
|
+
x-" data-x="5.45" data-y="-1" cx="528.2758620689655" cy="407.44827586206895" r="3" fill="hsl(273, 100%, 50%, 0.8)" />
|
|
46
|
+
</g>
|
|
47
|
+
<g>
|
|
48
|
+
<circle data-type="point" data-label="D2.2
|
|
49
|
+
x+" data-x="6.55" data-y="-1" cx="588.9655172413793" cy="407.44827586206895" r="3" fill="hsl(274, 100%, 50%, 0.8)" />
|
|
50
|
+
</g>
|
|
51
|
+
<g>
|
|
52
|
+
<circle data-type="point" data-label="anchorPoint
|
|
53
|
+
orientation: y+" data-x="-2.075" data-y="2.2" cx="113.10344827586206" cy="230.89655172413794" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
54
|
+
</g>
|
|
55
|
+
<g>
|
|
56
|
+
<circle data-type="point" data-label="anchorPoint
|
|
57
|
+
orientation: y-" data-x="-2.499" data-y="1.5990000000000002" cx="89.7103448275862" cy="264.0551724137931" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
58
|
+
</g>
|
|
59
|
+
<g>
|
|
60
|
+
<circle data-type="point" data-label="anchorPoint
|
|
61
|
+
orientation: y-" data-x="6.65" data-y="-1" cx="594.4827586206897" cy="407.44827586206895" 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="2.25" data-y="-1" cx="351.7241379310345" cy="407.44827586206895" 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="4.5" data-y="1" cx="475.8620689655172" cy="297.1034482758621" 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="4.5" data-y="-1" cx="475.8620689655172" cy="407.44827586206895" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
74
|
+
</g>
|
|
75
|
+
<g>
|
|
76
|
+
<polyline data-points="-2.6,2.2 -0.5,2" data-type="line" data-label="" points="84.13793103448276,230.89655172413794 200,241.93103448275863" fill="none" stroke="hsl(0, 100%, 50%, 0.8)" stroke-width="1" />
|
|
77
|
+
</g>
|
|
78
|
+
<g>
|
|
79
|
+
<polyline data-points="0.5,2 2.45,1" data-type="line" data-label="" points="255.17241379310343,241.93103448275863 362.7586206896552,297.1034482758621" fill="none" stroke="hsl(304, 100%, 50%, 0.8)" stroke-width="1" />
|
|
80
|
+
</g>
|
|
81
|
+
<g>
|
|
82
|
+
<polyline data-points="0.5,2 2.45,-1" data-type="line" data-label="" points="255.17241379310343,241.93103448275863 362.7586206896552,407.44827586206895" fill="none" stroke="hsl(304, 100%, 50%, 0.8)" stroke-width="1" />
|
|
83
|
+
</g>
|
|
84
|
+
<g>
|
|
85
|
+
<polyline data-points="3.55,1 5.45,1" data-type="line" data-label="" points="423.44827586206895,297.1034482758621 528.2758620689655,297.1034482758621" fill="none" stroke="hsl(312, 100%, 50%, 0.8)" stroke-width="1" />
|
|
86
|
+
</g>
|
|
87
|
+
<g>
|
|
88
|
+
<polyline data-points="3.55,-1 5.45,-1" data-type="line" data-label="" points="423.44827586206895,407.44827586206895 528.2758620689655,407.44827586206895" fill="none" stroke="hsl(320, 100%, 50%, 0.8)" stroke-width="1" />
|
|
89
|
+
</g>
|
|
90
|
+
<g>
|
|
91
|
+
<polyline data-points="-2.6,1.8 6.55,1" data-type="line" data-label="" points="84.13793103448276,252.9655172413793 588.9655172413793,297.1034482758621" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
92
|
+
</g>
|
|
93
|
+
<g>
|
|
94
|
+
<polyline data-points="-2.6,1.8 6.55,-1" data-type="line" data-label="" points="84.13793103448276,252.9655172413793 588.9655172413793,407.44827586206895" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
95
|
+
</g>
|
|
96
|
+
<g>
|
|
97
|
+
<polyline data-points="6.55,1 6.55,-1" data-type="line" data-label="" points="588.9655172413793,297.1034482758621 588.9655172413793,407.44827586206895" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
98
|
+
</g>
|
|
99
|
+
<g>
|
|
100
|
+
<polyline data-points="-2.6,2.2 -1.55,2.2 -1.55,2 -0.5,2" data-type="line" data-label="" points="84.13793103448276,230.89655172413794 142.06896551724137,230.89655172413794 142.06896551724137,241.93103448275863 200,241.93103448275863" fill="none" stroke="purple" stroke-width="1" />
|
|
101
|
+
</g>
|
|
102
|
+
<g>
|
|
103
|
+
<polyline data-points="2.45,-1 2.25,-1 2.25,1 2.45,1" data-type="line" data-label="" points="362.7586206896552,407.44827586206895 351.7241379310345,407.44827586206895 351.7241379310345,297.1034482758621 362.7586206896552,297.1034482758621" fill="none" stroke="purple" stroke-width="1" />
|
|
104
|
+
</g>
|
|
105
|
+
<g>
|
|
106
|
+
<polyline data-points="0.5,2 1.475,2 1.475,1 2.45,1" data-type="line" data-label="" points="255.17241379310343,241.93103448275863 308.9655172413793,241.93103448275863 308.9655172413793,297.1034482758621 362.7586206896552,297.1034482758621" fill="none" stroke="purple" stroke-width="1" />
|
|
107
|
+
</g>
|
|
108
|
+
<g>
|
|
109
|
+
<polyline data-points="3.55,1 5.45,1" data-type="line" data-label="" points="423.44827586206895,297.1034482758621 528.2758620689655,297.1034482758621" fill="none" stroke="purple" stroke-width="1" />
|
|
110
|
+
</g>
|
|
111
|
+
<g>
|
|
112
|
+
<polyline data-points="3.55,-1 5.45,-1" data-type="line" data-label="" points="423.44827586206895,407.44827586206895 528.2758620689655,407.44827586206895" fill="none" stroke="purple" stroke-width="1" />
|
|
113
|
+
</g>
|
|
114
|
+
<g>
|
|
115
|
+
<polyline data-points="6.55,-1 6.75,-1 6.75,1 6.55,1" data-type="line" data-label="" points="588.9655172413793,407.44827586206895 600,407.44827586206895 600,297.1034482758621 588.9655172413793,297.1034482758621" fill="none" stroke="purple" stroke-width="1" />
|
|
116
|
+
</g>
|
|
117
|
+
<g>
|
|
118
|
+
<polyline data-points="-2.6,1.8 -2.499,1.8 -2.499,1.5990000000000002" data-type="line" data-label="" points="84.13793103448276,252.9655172413793 89.7103448275862,252.9655172413793 89.7103448275862,264.0551724137931" fill="none" stroke="purple" stroke-width="1" />
|
|
119
|
+
</g>
|
|
120
|
+
<g>
|
|
121
|
+
<rect data-type="rect" data-label="BT1" data-x="-3" data-y="2" x="40" y="219.86206896551727" width="44.13793103448276" height="44.13793103448273" fill="hsl(199, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018125000000000002" />
|
|
122
|
+
</g>
|
|
123
|
+
<g>
|
|
124
|
+
<rect data-type="rect" data-label="SW1" data-x="0" data-y="2" x="200" y="219.86206896551727" width="55.17241379310343" height="44.13793103448273" fill="hsl(69, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018125000000000002" />
|
|
125
|
+
</g>
|
|
126
|
+
<g>
|
|
127
|
+
<rect data-type="rect" data-label="R1" data-x="3" data-y="1" x="362.7586206896552" y="286.3748772413793" width="60.68965517241378" height="21.45714206896554" fill="hsl(71, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018125000000000002" />
|
|
128
|
+
</g>
|
|
129
|
+
<g>
|
|
130
|
+
<rect data-type="rect" data-label="R2" data-x="3" data-y="-1" x="362.7586206896552" y="396.7197048275862" width="60.68965517241378" height="21.45714206896554" fill="hsl(72, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018125000000000002" />
|
|
131
|
+
</g>
|
|
132
|
+
<g>
|
|
133
|
+
<rect data-type="rect" data-label="D1" data-x="6" data-y="1" x="528.2758620689655" y="286.3748772413793" width="60.689655172413836" height="21.45714206896554" fill="hsl(357, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018125000000000002" />
|
|
134
|
+
</g>
|
|
135
|
+
<g>
|
|
136
|
+
<rect data-type="rect" data-label="D2" data-x="6" data-y="-1" x="528.2758620689655" y="396.7197048275862" width="60.689655172413836" height="21.45714206896554" fill="hsl(358, 100%, 50%, 0.8)" stroke="black" stroke-width="0.018125000000000002" />
|
|
137
|
+
</g>
|
|
138
|
+
<g>
|
|
139
|
+
<rect data-type="rect" data-label="netId: BT1.plus to SW1.in
|
|
140
|
+
globalConnNetId: connectivity_net0" data-x="-2.075" data-y="2.4250000000000003" x="107.5862068965517" y="206.06896551724137" width="11.034482758620712" height="24.82758620689657" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018125000000000002" />
|
|
141
|
+
</g>
|
|
142
|
+
<g>
|
|
143
|
+
<rect data-type="rect" data-label="netId: GND
|
|
144
|
+
globalConnNetId: connectivity_net4" data-x="-2.499" data-y="1.3590000000000002" x="84.19310344827585" y="264.0551724137931" width="11.034482758620697" height="26.48275862068965" fill="#00000066" stroke="#000000" stroke-width="0.018125000000000002" />
|
|
145
|
+
</g>
|
|
146
|
+
<g>
|
|
147
|
+
<rect data-type="rect" data-label="netId: GND
|
|
148
|
+
globalConnNetId: connectivity_net4" data-x="6.65" data-y="-1.24" x="588.9655172413793" y="407.44827586206895" width="11.034482758620697" height="26.48275862068965" fill="#00000066" stroke="#000000" stroke-width="0.018125000000000002" />
|
|
149
|
+
</g>
|
|
150
|
+
<g>
|
|
151
|
+
<rect data-type="rect" data-label="netId: SW1.out to R2.left
|
|
152
|
+
globalConnNetId: connectivity_net1" data-x="2.25" data-y="-1.225" x="346.2068965517241" y="407.44827586206895" width="11.034482758620697" height="24.82758620689657" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018125000000000002" />
|
|
153
|
+
</g>
|
|
154
|
+
<g>
|
|
155
|
+
<rect data-type="rect" data-label="netId: R1.right to D1.a
|
|
156
|
+
globalConnNetId: connectivity_net2" data-x="4.5" data-y="1.225" x="470.34482758620686" y="272.2758620689655" width="11.034482758620697" height="24.82758620689657" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018125000000000002" />
|
|
157
|
+
</g>
|
|
158
|
+
<g>
|
|
159
|
+
<rect data-type="rect" data-label="netId: R2.right to D2.a
|
|
160
|
+
globalConnNetId: connectivity_net3" data-x="4.5" data-y="-0.775" x="470.34482758620686" y="382.62068965517244" width="11.034482758620697" height="24.827586206896513" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.018125000000000002" />
|
|
161
|
+
</g>
|
|
162
|
+
<g id="crosshair" style="display: none">
|
|
163
|
+
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
164
|
+
<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>
|
|
165
|
+
</g>
|
|
166
|
+
<script>
|
|
167
|
+
<![CDATA[
|
|
168
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
169
|
+
const svg = e.currentTarget;
|
|
170
|
+
const rect = svg.getBoundingClientRect();
|
|
171
|
+
const x = e.clientX - rect.left;
|
|
172
|
+
const y = e.clientY - rect.top;
|
|
173
|
+
const crosshair = svg.getElementById('crosshair');
|
|
174
|
+
const h = svg.getElementById('crosshair-h');
|
|
175
|
+
const v = svg.getElementById('crosshair-v');
|
|
176
|
+
const coords = svg.getElementById('coordinates');
|
|
177
|
+
|
|
178
|
+
crosshair.style.display = 'block';
|
|
179
|
+
h.setAttribute('x1', '0');
|
|
180
|
+
h.setAttribute('x2', '640');
|
|
181
|
+
h.setAttribute('y1', y);
|
|
182
|
+
h.setAttribute('y2', y);
|
|
183
|
+
v.setAttribute('x1', x);
|
|
184
|
+
v.setAttribute('x2', x);
|
|
185
|
+
v.setAttribute('y1', '0');
|
|
186
|
+
v.setAttribute('y2', '640');
|
|
187
|
+
|
|
188
|
+
// Calculate real coordinates using inverse transformation
|
|
189
|
+
const matrix = {
|
|
190
|
+
"a": 55.172413793103445,
|
|
191
|
+
"c": 0,
|
|
192
|
+
"e": 227.58620689655172,
|
|
193
|
+
"b": 0,
|
|
194
|
+
"d": -55.172413793103445,
|
|
195
|
+
"f": 352.2758620689655
|
|
196
|
+
};
|
|
197
|
+
// Manually invert and apply the affine transform
|
|
198
|
+
// Since we only use translate and scale, we can directly compute:
|
|
199
|
+
// x' = (x - tx) / sx
|
|
200
|
+
// y' = (y - ty) / sy
|
|
201
|
+
const sx = matrix.a;
|
|
202
|
+
const sy = matrix.d;
|
|
203
|
+
const tx = matrix.e;
|
|
204
|
+
const ty = matrix.f;
|
|
205
|
+
const realPoint = {
|
|
206
|
+
x: (x - tx) / sx,
|
|
207
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
211
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
212
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
213
|
+
});
|
|
214
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
215
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
216
|
+
});
|
|
217
|
+
]]>
|
|
218
|
+
</script>
|
|
219
|
+
</svg>
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "BT1",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": -3,
|
|
7
|
+
"y": 2
|
|
8
|
+
},
|
|
9
|
+
"width": 0.8,
|
|
10
|
+
"height": 0.8,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "BT1.1",
|
|
14
|
+
"x": -2.6,
|
|
15
|
+
"y": 2.2
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pinId": "BT1.2",
|
|
19
|
+
"x": -2.6,
|
|
20
|
+
"y": 1.8
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"chipId": "SW1",
|
|
26
|
+
"center": {
|
|
27
|
+
"x": 0,
|
|
28
|
+
"y": 2
|
|
29
|
+
},
|
|
30
|
+
"width": 1,
|
|
31
|
+
"height": 0.8,
|
|
32
|
+
"pins": [
|
|
33
|
+
{
|
|
34
|
+
"pinId": "SW1.1",
|
|
35
|
+
"x": -0.5,
|
|
36
|
+
"y": 2
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"pinId": "SW1.2",
|
|
40
|
+
"x": 0.5,
|
|
41
|
+
"y": 2
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"chipId": "R1",
|
|
47
|
+
"center": {
|
|
48
|
+
"x": 3,
|
|
49
|
+
"y": 1
|
|
50
|
+
},
|
|
51
|
+
"width": 1.06,
|
|
52
|
+
"height": 0.3889107,
|
|
53
|
+
"pins": [
|
|
54
|
+
{
|
|
55
|
+
"pinId": "R1.1",
|
|
56
|
+
"x": 2.45,
|
|
57
|
+
"y": 1
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"pinId": "R1.2",
|
|
61
|
+
"x": 3.55,
|
|
62
|
+
"y": 1
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"chipId": "R2",
|
|
68
|
+
"center": {
|
|
69
|
+
"x": 3,
|
|
70
|
+
"y": -1
|
|
71
|
+
},
|
|
72
|
+
"width": 1.06,
|
|
73
|
+
"height": 0.3889107,
|
|
74
|
+
"pins": [
|
|
75
|
+
{
|
|
76
|
+
"pinId": "R2.1",
|
|
77
|
+
"x": 2.45,
|
|
78
|
+
"y": -1
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"pinId": "R2.2",
|
|
82
|
+
"x": 3.55,
|
|
83
|
+
"y": -1
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"chipId": "D1",
|
|
89
|
+
"center": {
|
|
90
|
+
"x": 6,
|
|
91
|
+
"y": 1
|
|
92
|
+
},
|
|
93
|
+
"width": 1.06,
|
|
94
|
+
"height": 0.3889107,
|
|
95
|
+
"pins": [
|
|
96
|
+
{
|
|
97
|
+
"pinId": "D1.1",
|
|
98
|
+
"x": 5.45,
|
|
99
|
+
"y": 1
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"pinId": "D1.2",
|
|
103
|
+
"x": 6.55,
|
|
104
|
+
"y": 1
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"chipId": "D2",
|
|
110
|
+
"center": {
|
|
111
|
+
"x": 6,
|
|
112
|
+
"y": -1
|
|
113
|
+
},
|
|
114
|
+
"width": 1.06,
|
|
115
|
+
"height": 0.3889107,
|
|
116
|
+
"pins": [
|
|
117
|
+
{
|
|
118
|
+
"pinId": "D2.1",
|
|
119
|
+
"x": 5.45,
|
|
120
|
+
"y": -1
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"pinId": "D2.2",
|
|
124
|
+
"x": 6.55,
|
|
125
|
+
"y": -1
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
],
|
|
130
|
+
"directConnections": [
|
|
131
|
+
{
|
|
132
|
+
"pinIds": ["BT1.1", "SW1.1"],
|
|
133
|
+
"netId": "BT1.plus to SW1.in"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"pinIds": ["SW1.2", "R1.1"],
|
|
137
|
+
"netId": "SW1.out to R1.left"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"pinIds": ["SW1.2", "R2.1"],
|
|
141
|
+
"netId": "SW1.out to R2.left"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"pinIds": ["R1.2", "D1.1"],
|
|
145
|
+
"netId": "R1.right to D1.a"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"pinIds": ["R2.2", "D2.1"],
|
|
149
|
+
"netId": "R2.right to D2.a"
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
"netConnections": [
|
|
153
|
+
{
|
|
154
|
+
"netId": "GND",
|
|
155
|
+
"pinIds": ["BT1.2", "D1.2", "D2.2"],
|
|
156
|
+
"netLabelWidth": 0.48
|
|
157
|
+
}
|
|
158
|
+
],
|
|
159
|
+
"availableNetLabelOrientations": {
|
|
160
|
+
"GND": ["y-"]
|
|
161
|
+
},
|
|
162
|
+
"maxMspPairDistance": 8
|
|
163
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import inputProblem from "./assets/bugreport-001-gnd-overlap.input.json"
|
|
4
|
+
import "tests/fixtures/matcher"
|
|
5
|
+
|
|
6
|
+
test("bugreport-001-gnd-overlap", () => {
|
|
7
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
|
+
solver.solve()
|
|
9
|
+
|
|
10
|
+
expect(
|
|
11
|
+
solver.netLabelPlacementSolver!.netLabelPlacements.some(
|
|
12
|
+
(placement) => placement.netId === "GND",
|
|
13
|
+
),
|
|
14
|
+
).toBe(true)
|
|
15
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
16
|
+
})
|