@tscircuit/schematic-trace-solver 0.0.99 → 0.0.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +25 -5
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/SchematicTraceSingleLineSolver2.ts +13 -1
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/mid.ts +13 -3
- package/package.json +1 -1
- package/tests/repros/__snapshots__/repro47-endpoint-obstacle-detour.snap.svg +65 -0
- package/tests/repros/__snapshots__/repro5-escape-padded-text-obstacles.snap.svg +74 -0
- package/tests/repros/assets/repro47-endpoint-obstacle-detour.input.json +133 -0
- package/tests/repros/assets/repro5-escape-padded-text-obstacles.input.json +202 -0
- package/tests/repros/repro47-endpoint-obstacle-detour.test.ts +19 -0
- package/tests/repros/repro5-escape-padded-text-obstacles.test.ts +17 -0
- package/tests/solvers/SchematicTraceSingleLineSolver2/candidate-mids-from-set.test.ts +39 -0
package/dist/index.js
CHANGED
|
@@ -801,6 +801,7 @@ var isPathCollidingWithObstacles = (path, obstacles) => {
|
|
|
801
801
|
|
|
802
802
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/mid.ts
|
|
803
803
|
var EPS2 = 1e-9;
|
|
804
|
+
var OBSTACLE_CLEARANCE = 0.2;
|
|
804
805
|
var aabbFromPoints = (a, b) => ({
|
|
805
806
|
minX: Math.min(a.x, b.x),
|
|
806
807
|
maxX: Math.max(a.x, b.x),
|
|
@@ -815,7 +816,7 @@ var midBetweenPointAndRect = (axis, p, r, eps = EPS2) => {
|
|
|
815
816
|
if (p.x > r.maxX + eps) {
|
|
816
817
|
return [(p.x + r.maxX) / 2];
|
|
817
818
|
}
|
|
818
|
-
return [r.minX -
|
|
819
|
+
return [r.minX - OBSTACLE_CLEARANCE, r.maxX + OBSTACLE_CLEARANCE];
|
|
819
820
|
} else {
|
|
820
821
|
if (p.y < r.minY - eps) {
|
|
821
822
|
return [(p.y + r.minY) / 2];
|
|
@@ -823,10 +824,11 @@ var midBetweenPointAndRect = (axis, p, r, eps = EPS2) => {
|
|
|
823
824
|
if (p.y > r.maxY + eps) {
|
|
824
825
|
return [(p.y + r.maxY) / 2];
|
|
825
826
|
}
|
|
826
|
-
return [r.minY -
|
|
827
|
+
return [r.minY - OBSTACLE_CLEARANCE, r.maxY + OBSTACLE_CLEARANCE];
|
|
827
828
|
}
|
|
828
829
|
};
|
|
829
|
-
var candidateMidsFromSet = (axis, colliding, collisionRects, aabb,
|
|
830
|
+
var candidateMidsFromSet = (axis, colliding, collisionRects, aabb, opts = {}) => {
|
|
831
|
+
const { allowOpenSideCandidates = false, eps = EPS2 } = opts;
|
|
830
832
|
const setRects = [...collisionRects];
|
|
831
833
|
if (axis === "x") {
|
|
832
834
|
const leftBoundaries = [aabb.minX, ...setRects.map((r) => r.maxX)].filter(
|
|
@@ -840,9 +842,13 @@ var candidateMidsFromSet = (axis, colliding, collisionRects, aabb, eps = EPS2) =
|
|
|
840
842
|
const out = [];
|
|
841
843
|
if (leftNeighbor !== void 0) {
|
|
842
844
|
out.push((leftNeighbor + colliding.minX) / 2);
|
|
845
|
+
} else if (allowOpenSideCandidates) {
|
|
846
|
+
out.push(colliding.minX - OBSTACLE_CLEARANCE);
|
|
843
847
|
}
|
|
844
848
|
if (rightNeighbor !== void 0) {
|
|
845
849
|
out.push((colliding.maxX + rightNeighbor) / 2);
|
|
850
|
+
} else if (allowOpenSideCandidates) {
|
|
851
|
+
out.push(colliding.maxX + OBSTACLE_CLEARANCE);
|
|
846
852
|
}
|
|
847
853
|
return out;
|
|
848
854
|
} else {
|
|
@@ -857,9 +863,13 @@ var candidateMidsFromSet = (axis, colliding, collisionRects, aabb, eps = EPS2) =
|
|
|
857
863
|
const out = [];
|
|
858
864
|
if (bottomNeighbor !== void 0) {
|
|
859
865
|
out.push((bottomNeighbor + colliding.minY) / 2);
|
|
866
|
+
} else if (allowOpenSideCandidates) {
|
|
867
|
+
out.push(colliding.minY - OBSTACLE_CLEARANCE);
|
|
860
868
|
}
|
|
861
869
|
if (topNeighbor !== void 0) {
|
|
862
870
|
out.push((colliding.maxY + topNeighbor) / 2);
|
|
871
|
+
} else if (allowOpenSideCandidates) {
|
|
872
|
+
out.push(colliding.maxY + OBSTACLE_CLEARANCE);
|
|
863
873
|
}
|
|
864
874
|
return out;
|
|
865
875
|
}
|
|
@@ -1318,6 +1328,9 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1318
1328
|
return;
|
|
1319
1329
|
}
|
|
1320
1330
|
const candidates = [];
|
|
1331
|
+
const candidateMidOptions = {
|
|
1332
|
+
allowOpenSideCandidates: this.connectionPair !== void 0
|
|
1333
|
+
};
|
|
1321
1334
|
if (collisionRects.size === 0) {
|
|
1322
1335
|
const m1 = midBetweenPointAndRect(axis, { x: PA.x, y: PA.y }, rect);
|
|
1323
1336
|
const m2 = midBetweenPointAndRect(axis, { x: PB.x, y: PB.y }, rect);
|
|
@@ -1325,7 +1338,13 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1325
1338
|
const uniqueCandidates = [...new Set(allCandidates)];
|
|
1326
1339
|
candidates.push(...uniqueCandidates);
|
|
1327
1340
|
} else {
|
|
1328
|
-
const mids = candidateMidsFromSet(
|
|
1341
|
+
const mids = candidateMidsFromSet(
|
|
1342
|
+
axis,
|
|
1343
|
+
rect,
|
|
1344
|
+
collisionRects,
|
|
1345
|
+
this.aabb,
|
|
1346
|
+
candidateMidOptions
|
|
1347
|
+
);
|
|
1329
1348
|
candidates.push(...mids);
|
|
1330
1349
|
}
|
|
1331
1350
|
const newStates = [];
|
|
@@ -1371,7 +1390,8 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
|
|
|
1371
1390
|
adjacentAxis,
|
|
1372
1391
|
rect,
|
|
1373
1392
|
collisionRects,
|
|
1374
|
-
this.aabb
|
|
1393
|
+
this.aabb,
|
|
1394
|
+
candidateMidOptions
|
|
1375
1395
|
)
|
|
1376
1396
|
);
|
|
1377
1397
|
}
|
|
@@ -413,6 +413,11 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
|
|
|
413
413
|
|
|
414
414
|
// Note: PA and PB are already defined above
|
|
415
415
|
const candidates: number[] = []
|
|
416
|
+
// Fixed MSP pairs may leave the endpoint bounds to complete a required
|
|
417
|
+
// route. Optional long-distance candidates retain their bounded search.
|
|
418
|
+
const candidateMidOptions = {
|
|
419
|
+
allowOpenSideCandidates: this.connectionPair !== undefined,
|
|
420
|
+
}
|
|
416
421
|
|
|
417
422
|
if (collisionRects.size === 0) {
|
|
418
423
|
// First collision on this search branch: use mid(PA, C) and mid(PB, C)
|
|
@@ -425,7 +430,13 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
|
|
|
425
430
|
candidates.push(...uniqueCandidates)
|
|
426
431
|
} else {
|
|
427
432
|
// Subsequent collisions: mid between C and nearest rect/bounds from the set
|
|
428
|
-
const mids = candidateMidsFromSet(
|
|
433
|
+
const mids = candidateMidsFromSet(
|
|
434
|
+
axis,
|
|
435
|
+
rect,
|
|
436
|
+
collisionRects,
|
|
437
|
+
this.aabb,
|
|
438
|
+
candidateMidOptions,
|
|
439
|
+
)
|
|
429
440
|
candidates.push(...mids)
|
|
430
441
|
}
|
|
431
442
|
|
|
@@ -496,6 +507,7 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
|
|
|
496
507
|
rect,
|
|
497
508
|
collisionRects,
|
|
498
509
|
this.aabb,
|
|
510
|
+
candidateMidOptions,
|
|
499
511
|
),
|
|
500
512
|
)
|
|
501
513
|
}
|
|
@@ -2,6 +2,7 @@ import type { Point } from "@tscircuit/math-utils"
|
|
|
2
2
|
import type { ObstacleRect } from "./rect"
|
|
3
3
|
|
|
4
4
|
const EPS = 1e-9
|
|
5
|
+
const OBSTACLE_CLEARANCE = 0.2
|
|
5
6
|
|
|
6
7
|
export type Axis = "x" | "y"
|
|
7
8
|
|
|
@@ -26,7 +27,7 @@ export const midBetweenPointAndRect = (
|
|
|
26
27
|
return [(p.x + r.maxX) / 2]
|
|
27
28
|
}
|
|
28
29
|
// Point is within rect bounds on this axis - generate candidates on both sides
|
|
29
|
-
return [r.minX -
|
|
30
|
+
return [r.minX - OBSTACLE_CLEARANCE, r.maxX + OBSTACLE_CLEARANCE]
|
|
30
31
|
} else {
|
|
31
32
|
if (p.y < r.minY - eps) {
|
|
32
33
|
return [(p.y + r.minY) / 2]
|
|
@@ -35,7 +36,7 @@ export const midBetweenPointAndRect = (
|
|
|
35
36
|
return [(p.y + r.maxY) / 2]
|
|
36
37
|
}
|
|
37
38
|
// Point is within rect bounds on this axis - generate candidates on both sides
|
|
38
|
-
return [r.minY -
|
|
39
|
+
return [r.minY - OBSTACLE_CLEARANCE, r.maxY + OBSTACLE_CLEARANCE]
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -44,8 +45,9 @@ export const candidateMidsFromSet = (
|
|
|
44
45
|
colliding: ObstacleRect,
|
|
45
46
|
collisionRects: Set<ObstacleRect>,
|
|
46
47
|
aabb: { minX: number; maxX: number; minY: number; maxY: number },
|
|
47
|
-
eps =
|
|
48
|
+
opts: { allowOpenSideCandidates?: boolean; eps?: number } = {},
|
|
48
49
|
): number[] => {
|
|
50
|
+
const { allowOpenSideCandidates = false, eps = EPS } = opts
|
|
49
51
|
const setRects = [...collisionRects]
|
|
50
52
|
|
|
51
53
|
if (axis === "x") {
|
|
@@ -64,9 +66,13 @@ export const candidateMidsFromSet = (
|
|
|
64
66
|
const out: number[] = []
|
|
65
67
|
if (leftNeighbor !== undefined) {
|
|
66
68
|
out.push((leftNeighbor + colliding.minX) / 2)
|
|
69
|
+
} else if (allowOpenSideCandidates) {
|
|
70
|
+
out.push(colliding.minX - OBSTACLE_CLEARANCE)
|
|
67
71
|
}
|
|
68
72
|
if (rightNeighbor !== undefined) {
|
|
69
73
|
out.push((colliding.maxX + rightNeighbor) / 2)
|
|
74
|
+
} else if (allowOpenSideCandidates) {
|
|
75
|
+
out.push(colliding.maxX + OBSTACLE_CLEARANCE)
|
|
70
76
|
}
|
|
71
77
|
return out
|
|
72
78
|
} else {
|
|
@@ -85,9 +91,13 @@ export const candidateMidsFromSet = (
|
|
|
85
91
|
const out: number[] = []
|
|
86
92
|
if (bottomNeighbor !== undefined) {
|
|
87
93
|
out.push((bottomNeighbor + colliding.minY) / 2)
|
|
94
|
+
} else if (allowOpenSideCandidates) {
|
|
95
|
+
out.push(colliding.minY - OBSTACLE_CLEARANCE)
|
|
88
96
|
}
|
|
89
97
|
if (topNeighbor !== undefined) {
|
|
90
98
|
out.push((colliding.maxY + topNeighbor) / 2)
|
|
99
|
+
} else if (allowOpenSideCandidates) {
|
|
100
|
+
out.push(colliding.maxY + OBSTACLE_CLEARANCE)
|
|
91
101
|
}
|
|
92
102
|
return out
|
|
93
103
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="0.6499999999999999,0.825 -0.6499999999999999,-0.825" data-type="line" data-label="" points="410.65315315315314,198.6036036036036 205.6981981981982,458.7387387387388" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.25,0.825 -1.25,-0.825" data-type="line" data-label="" points="505.2477477477478,198.6036036036036 111.1036036036036,458.7387387387388" fill="none" stroke="hsl(224, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.49999999999999994,-0.725 -1.25,0.825" data-type="line" data-label="" points="387.0045045045045,442.97297297297297 111.1036036036036,198.6036036036036" fill="none" stroke="hsl(168, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="1.4,-0.725 -0.6499999999999999,0.825" data-type="line" data-label="" points="528.8963963963964,442.97297297297297 205.6981981981982,198.6036036036036" fill="none" stroke="hsl(168, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="0.6499999999999999,0.825 0,0.825 0,-0.825 -0.6499999999999999,-0.825" data-type="line" data-label="" points="410.65315315315314,198.6036036036036 308.1756756756757,198.6036036036036 308.1756756756757,458.7387387387388 205.6981981981982,458.7387387387388" fill="none" stroke="purple" stroke-width="1px"/></g><g><polyline data-points="1.25,0.825 1.4500000000000002,0.825 1.4500000000000002,0 -1.45,0 -1.45,-0.825 -1.25,-0.825" data-type="line" data-label="" points="505.2477477477478,198.6036036036036 536.7792792792793,198.6036036036036 536.7792792792793,328.6711711711712 79.57207207207207,328.6711711711712 79.57207207207207,458.7387387387388 111.1036036036036,458.7387387387388" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="-0.95" data-y="0.825" x="111.10360360360359" y="145" width="94.59459459459461" height="107.20720720720723" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="0.95" data-y="0.825" x="410.6531531531532" y="145" width="94.59459459459464" height="107.20720720720723" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="schematic_component_2" data-x="-0.95" data-y="-0.825" x="111.10360360360359" y="405.13513513513516" width="94.59459459459461" height="107.20720720720726" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="schematic_component_3" data-x="0.95" data-y="-0.825" x="387.00450450450455" y="414.9290282263514" width="141.89189189189193" height="87.61942102477474" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="netId: .J1 > .pin1 to .R1 > .pin1
|
|
2
|
+
globalConnNetId: connectivity_net2" data-x="0.2739999999999999" data-y="-0.725" x="315.9009009009009" y="427.20720720720715" width="70.94594594594594" height="31.531531531531584" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="netId: .J1 > .pin1 to .R1 > .pin1
|
|
3
|
+
globalConnNetId: connectivity_net2" data-x="-1.476" data-y="0.825" x="39.999999999999986" y="182.8378378378378" width="70.94594594594597" height="31.531531531531556" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="netId: .J1 > .pin3 to .R1 > .pin2
|
|
4
|
+
globalConnNetId: connectivity_net3" data-x="1.626" data-y="-0.725" x="529.0540540540542" y="427.20720720720715" width="70.94594594594594" height="31.531531531531584" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="netId: .J1 > .pin3 to .R1 > .pin2
|
|
5
|
+
globalConnNetId: connectivity_net3" data-x="-0.42399999999999993" data-y="0.825" x="205.85585585585585" y="182.8378378378378" width="70.94594594594594" height="31.531531531531556" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="netId: .R2 > .pin1 to .R3 > .pin2
|
|
6
|
+
globalConnNetId: connectivity_net0" data-x="0.32499999999999996" data-y="1.05" x="343.64864864864865" y="127.65765765765765" width="31.531531531531527" height="70.94594594594597" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.006342857142857142"/></g><g><rect data-type="rect" data-label="netId: .R2 > .pin2 to .R3 > .pin1
|
|
7
|
+
globalConnNetId: connectivity_net1" data-x="1.4500000000000002" data-y="1.05" x="521.0135135135135" y="127.65765765765765" width="31.531531531531527" height="70.94594594594597" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.006342857142857142"/></g><g><circle data-type="point" data-label="R1.1
|
|
8
|
+
x-" data-x="-1.25" data-y="0.825" cx="111.1036036036036" cy="198.6036036036036" r="3" fill="hsl(226, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="R1.2
|
|
9
|
+
x+" data-x="-0.6499999999999999" data-y="0.825" cx="205.6981981981982" cy="198.6036036036036" r="3" fill="hsl(227, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="R2.1
|
|
10
|
+
x-" data-x="0.6499999999999999" data-y="0.825" cx="410.65315315315314" cy="198.6036036036036" r="3" fill="hsl(107, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="R2.2
|
|
11
|
+
x+" data-x="1.25" data-y="0.825" cx="505.2477477477478" cy="198.6036036036036" r="3" fill="hsl(108, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="R3.1
|
|
12
|
+
x-" data-x="-1.25" data-y="-0.825" cx="111.1036036036036" cy="458.7387387387388" r="3" fill="hsl(348, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="R3.2
|
|
13
|
+
x+" data-x="-0.6499999999999999" data-y="-0.825" cx="205.6981981981982" cy="458.7387387387388" r="3" fill="hsl(349, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J1.1
|
|
14
|
+
x-" data-x="0.49999999999999994" data-y="-0.725" cx="387.0045045045045" cy="442.97297297297297" r="3" fill="hsl(218, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J1.2
|
|
15
|
+
y-" data-x="0.95" data-y="-1.1028787352499998" cx="457.9504504504505" cy="502.5484492511261" r="3" fill="hsl(219, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="J1.3
|
|
16
|
+
x+" data-x="1.4" data-y="-0.725" cx="528.8963963963964" cy="442.97297297297297" r="3" fill="hsl(220, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
17
|
+
orientation: x-" data-x="0.49999999999999994" data-y="-0.725" cx="387.0045045045045" cy="442.97297297297297" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
18
|
+
orientation: x-" data-x="-1.25" data-y="0.825" cx="111.1036036036036" cy="198.6036036036036" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
19
|
+
orientation: x+" data-x="1.4" data-y="-0.725" cx="528.8963963963964" cy="442.97297297297297" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
20
|
+
orientation: x+" data-x="-0.6499999999999999" data-y="0.825" cx="205.6981981981982" cy="198.6036036036036" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
21
|
+
orientation: y+" data-x="0.32499999999999996" data-y="0.825" cx="359.4144144144144" cy="198.6036036036036" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
22
|
+
orientation: y+" data-x="1.4500000000000002" data-y="0.825" cx="536.7792792792793" cy="198.6036036036036" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5"/><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></g><script><![CDATA[
|
|
23
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
24
|
+
const svg = e.currentTarget;
|
|
25
|
+
const rect = svg.getBoundingClientRect();
|
|
26
|
+
const x = e.clientX - rect.left;
|
|
27
|
+
const y = e.clientY - rect.top;
|
|
28
|
+
const crosshair = svg.getElementById('crosshair');
|
|
29
|
+
const h = svg.getElementById('crosshair-h');
|
|
30
|
+
const v = svg.getElementById('crosshair-v');
|
|
31
|
+
const coords = svg.getElementById('coordinates');
|
|
32
|
+
|
|
33
|
+
crosshair.style.display = 'block';
|
|
34
|
+
h.setAttribute('x1', '0');
|
|
35
|
+
h.setAttribute('x2', '640');
|
|
36
|
+
h.setAttribute('y1', y);
|
|
37
|
+
h.setAttribute('y2', y);
|
|
38
|
+
v.setAttribute('x1', x);
|
|
39
|
+
v.setAttribute('x2', x);
|
|
40
|
+
v.setAttribute('y1', '0');
|
|
41
|
+
v.setAttribute('y2', '640');
|
|
42
|
+
|
|
43
|
+
// Calculate real coordinates using inverse transformation
|
|
44
|
+
const matrix = {"a":157.65765765765767,"c":0,"e":308.1756756756757,"b":0,"d":-157.65765765765767,"f":328.6711711711712};
|
|
45
|
+
// Manually invert and apply the affine transform
|
|
46
|
+
// Since we only use translate and scale, we can directly compute:
|
|
47
|
+
// x' = (x - tx) / sx
|
|
48
|
+
// y' = (y - ty) / sy
|
|
49
|
+
const sx = matrix.a;
|
|
50
|
+
const sy = matrix.d;
|
|
51
|
+
const tx = matrix.e;
|
|
52
|
+
const ty = matrix.f;
|
|
53
|
+
const realPoint = {
|
|
54
|
+
x: (x - tx) / sx,
|
|
55
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
59
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
60
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
61
|
+
});
|
|
62
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
63
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
64
|
+
});
|
|
65
|
+
]]></script></svg>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="2.52,1 -0.9,0.7999999999999999" data-type="line" data-label="" points="476.7266775777414,259.0507364975451 163.27332242225856,277.3813420621932" fill="none" stroke="hsl(248, 100%, 50%, 0.8)" stroke-width="1px"/></g><g><polyline data-points="2.5200000000000005,1 2.7200000000000006,1 2.7200000000000006,3.3900000000000006 -1.1,3.3900000000000006 -1.1,0.7999999999999999 -0.9,0.7999999999999999" data-type="line" data-label="" points="476.7266775777414,259.0507364975451 495.0572831423895,259.0507364975451 495.0572831423895,40 144.94271685761043,40 144.94271685761043,277.3813420621932 163.27332242225856,277.3813420621932" fill="none" stroke="purple" stroke-width="1px"/></g><g><rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="163.27332242225856" y="121.57119476268417" width="164.97545008183306" height="458.26513911620293" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.010910714285714287"/></g><g><rect data-type="rect" data-label="schematic_component_1" data-x="2" data-y="1.0699999999999998" x="381.40752864157116" y="221.4729950900164" width="95.31914893617022" height="62.324058919803605" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.010910714285714287"/></g><g><rect data-type="rect" data-label="part-number" data-x="0.15999999999999992" data-y="-2.63" x="199.93453355155478" y="583.5024549918166" width="120.98199672667755" height="16.49754500818335" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.010910714285714287"/></g><g><rect data-type="rect" data-label="U1" data-x="-0.38" data-y="2.615" x="194.43535188216038" y="99.57446808510645" width="32.99509001636659" height="22.91325695581014" fill="rgba(160, 0, 220, 0.14)" stroke="black" stroke-width="0.010910714285714287"/></g><g><rect data-type="rect" data-label="netId: .LED1 > port.right to .U1 > .pin20
|
|
2
|
+
globalConnNetId: connectivity_net0" data-x="2.6200000000000006" data-y="0.775" x="476.7266775777414" y="259.0507364975451" width="18.330605564648124" height="41.243862520458265" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.010910714285714287"/></g><g><circle data-type="point" data-label="U1.1
|
|
3
|
+
x+" data-x="0.9" data-y="1.2" cx="328.2487725040916" cy="240.72013093289695" r="3" fill="hsl(319, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.2
|
|
4
|
+
x+" data-x="0.9" data-y="0.3999999999999999" cx="328.2487725040916" cy="314.04255319148945" r="3" fill="hsl(320, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.3
|
|
5
|
+
x+" data-x="0.9" data-y="0.5999999999999999" cx="328.2487725040916" cy="295.7119476268413" r="3" fill="hsl(321, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.4
|
|
6
|
+
x-" data-x="-0.9" data-y="0.3999999999999999" cx="163.27332242225856" cy="314.04255319148945" r="3" fill="hsl(322, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.5
|
|
7
|
+
x+" data-x="0.9" data-y="0.9999999999999998" cx="328.2487725040916" cy="259.0507364975451" r="3" fill="hsl(323, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.6
|
|
8
|
+
x+" data-x="0.9" data-y="-0.19999999999999996" cx="328.2487725040916" cy="369.03436988543376" r="3" fill="hsl(324, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.7
|
|
9
|
+
x-" data-x="-0.9" data-y="-0.7999999999999998" cx="163.27332242225856" cy="424.0261865793781" r="3" fill="hsl(325, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.9
|
|
10
|
+
x+" data-x="0.9" data-y="0.19999999999999996" cx="328.2487725040916" cy="332.3731587561375" r="3" fill="hsl(327, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.10
|
|
11
|
+
x+" data-x="0.9" data-y="0" cx="328.2487725040916" cy="350.70376432078564" r="3" fill="hsl(217, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.11
|
|
12
|
+
x+" data-x="0.9" data-y="0.7999999999999998" cx="328.2487725040916" cy="277.3813420621932" r="3" fill="hsl(218, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.12
|
|
13
|
+
x+" data-x="0.9" data-y="-1.2" cx="328.2487725040916" cy="460.6873977086743" r="3" fill="hsl(219, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.13
|
|
14
|
+
x+" data-x="0.9" data-y="-1" cx="328.2487725040916" cy="442.3567921440262" r="3" fill="hsl(220, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.14
|
|
15
|
+
x+" data-x="0.9" data-y="-0.7999999999999999" cx="328.2487725040916" cy="424.0261865793781" r="3" fill="hsl(221, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.15
|
|
16
|
+
x-" data-x="-0.9" data-y="1" cx="163.27332242225856" cy="259.0507364975451" r="3" fill="hsl(222, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.16
|
|
17
|
+
x-" data-x="-0.9" data-y="1.2" cx="163.27332242225856" cy="240.72013093289695" r="3" fill="hsl(223, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.17
|
|
18
|
+
x-" data-x="-0.9" data-y="0.5999999999999999" cx="163.27332242225856" cy="295.7119476268413" r="3" fill="hsl(224, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.18
|
|
19
|
+
x-" data-x="-0.9" data-y="-0.9999999999999998" cx="163.27332242225856" cy="442.3567921440262" r="3" fill="hsl(225, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.19
|
|
20
|
+
x-" data-x="-0.9" data-y="-0.19999999999999996" cx="163.27332242225856" cy="369.03436988543376" r="3" fill="hsl(226, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.20
|
|
21
|
+
x-" data-x="-0.9" data-y="0.7999999999999999" cx="163.27332242225856" cy="277.3813420621932" r="3" fill="hsl(248, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.21
|
|
22
|
+
x-" data-x="-0.9" data-y="-1.2" cx="163.27332242225856" cy="460.6873977086743" r="3" fill="hsl(249, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.22
|
|
23
|
+
x+" data-x="0.9" data-y="-0.5999999999999999" cx="328.2487725040916" cy="405.69558101472995" r="3" fill="hsl(250, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.23
|
|
24
|
+
x+" data-x="0.9" data-y="-0.3999999999999999" cx="328.2487725040916" cy="387.36497545008183" r="3" fill="hsl(251, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.25
|
|
25
|
+
x-" data-x="-0.9" data-y="-0.5999999999999999" cx="163.27332242225856" cy="405.69558101472995" r="3" fill="hsl(253, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.26
|
|
26
|
+
x-" data-x="-0.9" data-y="-0.3999999999999999" cx="163.27332242225856" cy="387.36497545008183" r="3" fill="hsl(254, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.27
|
|
27
|
+
x-" data-x="-0.9" data-y="0.19999999999999996" cx="163.27332242225856" cy="332.3731587561375" r="3" fill="hsl(255, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="U1.28
|
|
28
|
+
x-" data-x="-0.9" data-y="0" cx="163.27332242225856" cy="350.70376432078564" r="3" fill="hsl(256, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="LED1.1
|
|
29
|
+
x-" data-x="1.48" data-y="1" cx="381.40752864157116" cy="259.0507364975451" r="3" fill="hsl(57, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="LED1.2
|
|
30
|
+
x+" data-x="2.52" data-y="1" cx="476.7266775777414" cy="259.0507364975451" r="3" fill="hsl(58, 100%, 50%, 0.8)"/></g><g><circle data-type="point" data-label="anchorPoint
|
|
31
|
+
orientation: y-" data-x="2.6200000000000006" data-y="1" cx="485.8919803600654" cy="259.0507364975451" r="3" fill="hsl(40, 100%, 50%, 0.9)"/></g><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5"/><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></g><script><![CDATA[
|
|
32
|
+
document.currentScript.parentElement.addEventListener('mousemove', (e) => {
|
|
33
|
+
const svg = e.currentTarget;
|
|
34
|
+
const rect = svg.getBoundingClientRect();
|
|
35
|
+
const x = e.clientX - rect.left;
|
|
36
|
+
const y = e.clientY - rect.top;
|
|
37
|
+
const crosshair = svg.getElementById('crosshair');
|
|
38
|
+
const h = svg.getElementById('crosshair-h');
|
|
39
|
+
const v = svg.getElementById('crosshair-v');
|
|
40
|
+
const coords = svg.getElementById('coordinates');
|
|
41
|
+
|
|
42
|
+
crosshair.style.display = 'block';
|
|
43
|
+
h.setAttribute('x1', '0');
|
|
44
|
+
h.setAttribute('x2', '640');
|
|
45
|
+
h.setAttribute('y1', y);
|
|
46
|
+
h.setAttribute('y2', y);
|
|
47
|
+
v.setAttribute('x1', x);
|
|
48
|
+
v.setAttribute('x2', x);
|
|
49
|
+
v.setAttribute('y1', '0');
|
|
50
|
+
v.setAttribute('y2', '640');
|
|
51
|
+
|
|
52
|
+
// Calculate real coordinates using inverse transformation
|
|
53
|
+
const matrix = {"a":91.65302782324058,"c":0,"e":245.7610474631751,"b":0,"d":-91.65302782324058,"f":350.70376432078564};
|
|
54
|
+
// Manually invert and apply the affine transform
|
|
55
|
+
// Since we only use translate and scale, we can directly compute:
|
|
56
|
+
// x' = (x - tx) / sx
|
|
57
|
+
// y' = (y - ty) / sy
|
|
58
|
+
const sx = matrix.a;
|
|
59
|
+
const sy = matrix.d;
|
|
60
|
+
const tx = matrix.e;
|
|
61
|
+
const ty = matrix.f;
|
|
62
|
+
const realPoint = {
|
|
63
|
+
x: (x - tx) / sx,
|
|
64
|
+
y: (y - ty) / sy // Flip y back since we used negative scale
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
|
|
68
|
+
coords.setAttribute('x', (x + 5).toString());
|
|
69
|
+
coords.setAttribute('y', (y - 5).toString());
|
|
70
|
+
});
|
|
71
|
+
document.currentScript.parentElement.addEventListener('mouseleave', () => {
|
|
72
|
+
document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
|
|
73
|
+
});
|
|
74
|
+
]]></script></svg>
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "schematic_component_0",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": -0.95,
|
|
7
|
+
"y": 0.825
|
|
8
|
+
},
|
|
9
|
+
"width": 0.6000000000000001,
|
|
10
|
+
"height": 0.6800000000000002,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "R1.1",
|
|
14
|
+
"x": -1.25,
|
|
15
|
+
"y": 0.825,
|
|
16
|
+
"_facingDirection": "x-"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"pinId": "R1.2",
|
|
20
|
+
"x": -0.6499999999999999,
|
|
21
|
+
"y": 0.825,
|
|
22
|
+
"_facingDirection": "x+"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"chipId": "schematic_component_1",
|
|
28
|
+
"center": {
|
|
29
|
+
"x": 0.95,
|
|
30
|
+
"y": 0.825
|
|
31
|
+
},
|
|
32
|
+
"width": 0.6000000000000001,
|
|
33
|
+
"height": 0.6800000000000002,
|
|
34
|
+
"pins": [
|
|
35
|
+
{
|
|
36
|
+
"pinId": "R2.1",
|
|
37
|
+
"x": 0.6499999999999999,
|
|
38
|
+
"y": 0.825,
|
|
39
|
+
"_facingDirection": "x-"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"pinId": "R2.2",
|
|
43
|
+
"x": 1.25,
|
|
44
|
+
"y": 0.825,
|
|
45
|
+
"_facingDirection": "x+"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"chipId": "schematic_component_2",
|
|
51
|
+
"center": {
|
|
52
|
+
"x": -0.95,
|
|
53
|
+
"y": -0.825
|
|
54
|
+
},
|
|
55
|
+
"width": 0.6000000000000001,
|
|
56
|
+
"height": 0.6800000000000002,
|
|
57
|
+
"pins": [
|
|
58
|
+
{
|
|
59
|
+
"pinId": "R3.1",
|
|
60
|
+
"x": -1.25,
|
|
61
|
+
"y": -0.825,
|
|
62
|
+
"_facingDirection": "x-"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"pinId": "R3.2",
|
|
66
|
+
"x": -0.6499999999999999,
|
|
67
|
+
"y": -0.825,
|
|
68
|
+
"_facingDirection": "x+"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"chipId": "schematic_component_3",
|
|
74
|
+
"center": {
|
|
75
|
+
"x": 0.95,
|
|
76
|
+
"y": -0.825
|
|
77
|
+
},
|
|
78
|
+
"width": 0.9,
|
|
79
|
+
"height": 0.5557574704999997,
|
|
80
|
+
"pins": [
|
|
81
|
+
{
|
|
82
|
+
"pinId": "J1.1",
|
|
83
|
+
"x": 0.49999999999999994,
|
|
84
|
+
"y": -0.725
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"pinId": "J1.2",
|
|
88
|
+
"x": 0.95,
|
|
89
|
+
"y": -1.1028787352499998
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"pinId": "J1.3",
|
|
93
|
+
"x": 1.4,
|
|
94
|
+
"y": -0.725
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"directConnections": [
|
|
100
|
+
{
|
|
101
|
+
"pinIds": [
|
|
102
|
+
"R2.1",
|
|
103
|
+
"R3.2"
|
|
104
|
+
],
|
|
105
|
+
"netId": ".R2 > .pin1 to .R3 > .pin2"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"pinIds": [
|
|
109
|
+
"R2.2",
|
|
110
|
+
"R3.1"
|
|
111
|
+
],
|
|
112
|
+
"netId": ".R2 > .pin2 to .R3 > .pin1"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"pinIds": [
|
|
116
|
+
"J1.1",
|
|
117
|
+
"R1.1"
|
|
118
|
+
],
|
|
119
|
+
"netId": ".J1 > .pin1 to .R1 > .pin1"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"pinIds": [
|
|
123
|
+
"J1.3",
|
|
124
|
+
"R1.2"
|
|
125
|
+
],
|
|
126
|
+
"netId": ".J1 > .pin3 to .R1 > .pin2"
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
"netConnections": [],
|
|
130
|
+
"textBoxes": [],
|
|
131
|
+
"availableNetLabelOrientations": {},
|
|
132
|
+
"maxMspPairDistance": 5
|
|
133
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
{
|
|
2
|
+
"chips": [
|
|
3
|
+
{
|
|
4
|
+
"chipId": "schematic_component_0",
|
|
5
|
+
"center": {
|
|
6
|
+
"x": 0,
|
|
7
|
+
"y": 0
|
|
8
|
+
},
|
|
9
|
+
"width": 1.8,
|
|
10
|
+
"height": 5,
|
|
11
|
+
"pins": [
|
|
12
|
+
{
|
|
13
|
+
"pinId": "U1.1",
|
|
14
|
+
"x": 0.9,
|
|
15
|
+
"y": 1.2
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"pinId": "U1.2",
|
|
19
|
+
"x": 0.9,
|
|
20
|
+
"y": 0.3999999999999999
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"pinId": "U1.3",
|
|
24
|
+
"x": 0.9,
|
|
25
|
+
"y": 0.5999999999999999
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"pinId": "U1.4",
|
|
29
|
+
"x": -0.9,
|
|
30
|
+
"y": 0.3999999999999999
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"pinId": "U1.5",
|
|
34
|
+
"x": 0.9,
|
|
35
|
+
"y": 0.9999999999999998
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"pinId": "U1.6",
|
|
39
|
+
"x": 0.9,
|
|
40
|
+
"y": -0.19999999999999996
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"pinId": "U1.7",
|
|
44
|
+
"x": -0.9,
|
|
45
|
+
"y": -0.7999999999999998
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"pinId": "U1.9",
|
|
49
|
+
"x": 0.9,
|
|
50
|
+
"y": 0.19999999999999996
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"pinId": "U1.10",
|
|
54
|
+
"x": 0.9,
|
|
55
|
+
"y": 0
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"pinId": "U1.11",
|
|
59
|
+
"x": 0.9,
|
|
60
|
+
"y": 0.7999999999999998
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"pinId": "U1.12",
|
|
64
|
+
"x": 0.9,
|
|
65
|
+
"y": -1.2
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"pinId": "U1.13",
|
|
69
|
+
"x": 0.9,
|
|
70
|
+
"y": -1
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"pinId": "U1.14",
|
|
74
|
+
"x": 0.9,
|
|
75
|
+
"y": -0.7999999999999999
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"pinId": "U1.15",
|
|
79
|
+
"x": -0.9,
|
|
80
|
+
"y": 1
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"pinId": "U1.16",
|
|
84
|
+
"x": -0.9,
|
|
85
|
+
"y": 1.2
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"pinId": "U1.17",
|
|
89
|
+
"x": -0.9,
|
|
90
|
+
"y": 0.5999999999999999
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"pinId": "U1.18",
|
|
94
|
+
"x": -0.9,
|
|
95
|
+
"y": -0.9999999999999998
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"pinId": "U1.19",
|
|
99
|
+
"x": -0.9,
|
|
100
|
+
"y": -0.19999999999999996
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"pinId": "U1.20",
|
|
104
|
+
"x": -0.9,
|
|
105
|
+
"y": 0.7999999999999999
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"pinId": "U1.21",
|
|
109
|
+
"x": -0.9,
|
|
110
|
+
"y": -1.2
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"pinId": "U1.22",
|
|
114
|
+
"x": 0.9,
|
|
115
|
+
"y": -0.5999999999999999
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"pinId": "U1.23",
|
|
119
|
+
"x": 0.9,
|
|
120
|
+
"y": -0.3999999999999999
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"pinId": "U1.25",
|
|
124
|
+
"x": -0.9,
|
|
125
|
+
"y": -0.5999999999999999
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"pinId": "U1.26",
|
|
129
|
+
"x": -0.9,
|
|
130
|
+
"y": -0.3999999999999999
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"pinId": "U1.27",
|
|
134
|
+
"x": -0.9,
|
|
135
|
+
"y": 0.19999999999999996
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"pinId": "U1.28",
|
|
139
|
+
"x": -0.9,
|
|
140
|
+
"y": 0
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"chipId": "schematic_component_1",
|
|
146
|
+
"center": {
|
|
147
|
+
"x": 2,
|
|
148
|
+
"y": 1.0699999999999998
|
|
149
|
+
},
|
|
150
|
+
"width": 1.04,
|
|
151
|
+
"height": 0.6799999999999999,
|
|
152
|
+
"pins": [
|
|
153
|
+
{
|
|
154
|
+
"pinId": "LED1.1",
|
|
155
|
+
"x": 1.48,
|
|
156
|
+
"y": 1,
|
|
157
|
+
"_facingDirection": "x-"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"pinId": "LED1.2",
|
|
161
|
+
"x": 2.52,
|
|
162
|
+
"y": 1,
|
|
163
|
+
"_facingDirection": "x+"
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
"directConnections": [
|
|
169
|
+
{
|
|
170
|
+
"pinIds": [
|
|
171
|
+
"LED1.2",
|
|
172
|
+
"U1.20"
|
|
173
|
+
],
|
|
174
|
+
"netId": ".LED1 > port.right to .U1 > .pin20"
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
"netConnections": [],
|
|
178
|
+
"textBoxes": [
|
|
179
|
+
{
|
|
180
|
+
"chipId": "schematic_component_0",
|
|
181
|
+
"center": {
|
|
182
|
+
"x": 0.15999999999999992,
|
|
183
|
+
"y": -2.63
|
|
184
|
+
},
|
|
185
|
+
"width": 1.3199999999999998,
|
|
186
|
+
"height": 0.17999999999999972,
|
|
187
|
+
"text": "part-number"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"chipId": "schematic_component_0",
|
|
191
|
+
"center": {
|
|
192
|
+
"x": -0.38,
|
|
193
|
+
"y": 2.615
|
|
194
|
+
},
|
|
195
|
+
"width": 0.36000000000000004,
|
|
196
|
+
"height": 0.24999999999999956,
|
|
197
|
+
"text": "U1"
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"availableNetLabelOrientations": {},
|
|
201
|
+
"maxMspPairDistance": 5
|
|
202
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import "tests/fixtures/matcher"
|
|
4
|
+
import inputProblem from "./assets/repro47-endpoint-obstacle-detour.input.json"
|
|
5
|
+
|
|
6
|
+
test("repro47: endpoint obstacle detours fall back to net labels", () => {
|
|
7
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
|
+
|
|
9
|
+
solver.solve()
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
solver
|
|
13
|
+
.schematicTraceLinesSolver!.failedConnectionPairs.map(
|
|
14
|
+
(pair) => pair.mspPairId,
|
|
15
|
+
)
|
|
16
|
+
.sort(),
|
|
17
|
+
).toEqual(["J1.1-R1.1", "J1.3-R1.2"])
|
|
18
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
19
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver"
|
|
3
|
+
import "tests/fixtures/matcher"
|
|
4
|
+
import inputProblem from "./assets/repro5-escape-padded-text-obstacles.input.json"
|
|
5
|
+
|
|
6
|
+
test("repro5: route escapes past padded text obstacles", () => {
|
|
7
|
+
const solver = new SchematicTracePipelineSolver(inputProblem as any)
|
|
8
|
+
|
|
9
|
+
solver.solve()
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
solver.schematicTraceLinesSolver!.failedConnectionPairs.map(
|
|
13
|
+
(pair) => pair.mspPairId,
|
|
14
|
+
),
|
|
15
|
+
).toEqual([])
|
|
16
|
+
expect(solver).toMatchSolverSnapshot(import.meta.path)
|
|
17
|
+
})
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { candidateMidsFromSet } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/mid"
|
|
3
|
+
import type { ObstacleRect } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver2/rect"
|
|
4
|
+
|
|
5
|
+
test("candidate mids include clearance beyond an open obstacle side", () => {
|
|
6
|
+
const previousObstacle: ObstacleRect = {
|
|
7
|
+
kind: "chip",
|
|
8
|
+
chipId: "U1",
|
|
9
|
+
minX: -0.9,
|
|
10
|
+
maxX: 0.9,
|
|
11
|
+
minY: -2.5,
|
|
12
|
+
maxY: 2.5,
|
|
13
|
+
}
|
|
14
|
+
const collidingObstacle: ObstacleRect = {
|
|
15
|
+
kind: "text_box",
|
|
16
|
+
textBox: {
|
|
17
|
+
center: { x: -0.38, y: 2.615 },
|
|
18
|
+
width: 0.36,
|
|
19
|
+
height: 0.25,
|
|
20
|
+
text: "U1",
|
|
21
|
+
},
|
|
22
|
+
minX: -1.01,
|
|
23
|
+
maxX: 0.25,
|
|
24
|
+
minY: 2.04,
|
|
25
|
+
maxY: 3.19,
|
|
26
|
+
}
|
|
27
|
+
const aabb = { minX: -0.9, maxX: 2.52, minY: 0.8, maxY: 1 }
|
|
28
|
+
const collisionRects = new Set([previousObstacle])
|
|
29
|
+
|
|
30
|
+
expect(
|
|
31
|
+
candidateMidsFromSet("y", collidingObstacle, collisionRects, aabb),
|
|
32
|
+
).toEqual([1.42])
|
|
33
|
+
|
|
34
|
+
expect(
|
|
35
|
+
candidateMidsFromSet("y", collidingObstacle, collisionRects, aabb, {
|
|
36
|
+
allowOpenSideCandidates: true,
|
|
37
|
+
}),
|
|
38
|
+
).toEqual([1.42, 3.39])
|
|
39
|
+
})
|