@tscircuit/schematic-trace-solver 0.0.28 → 0.0.29
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 +71 -4
- package/lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver/generateElbowVariants.ts +129 -6
- package/package.json +1 -1
- package/site/examples/example08.page.tsx +1 -1
- package/tests/examples/__snapshots__/example01.snap.svg +29 -32
- package/tests/examples/__snapshots__/example02.snap.svg +5 -5
- package/tests/examples/__snapshots__/example04.snap.svg +12 -12
- package/tests/examples/__snapshots__/example05.snap.svg +35 -35
- package/tests/examples/__snapshots__/example06.snap.svg +14 -14
- package/tests/examples/__snapshots__/example08.snap.svg +23 -29
- package/tests/examples/__snapshots__/example11.snap.svg +33 -39
- package/tests/examples/__snapshots__/example12.snap.svg +29 -32
- package/tests/examples/__snapshots__/example13.snap.svg +84 -87
- package/tests/examples/__snapshots__/example15.snap.svg +57 -57
package/dist/index.js
CHANGED
|
@@ -469,6 +469,68 @@ var dir = (facingDirection) => {
|
|
|
469
469
|
// lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver/generateElbowVariants.ts
|
|
470
470
|
var EPS = 1e-6;
|
|
471
471
|
var MIN_LEN = 1e-6;
|
|
472
|
+
var checkIfUTurnNeeded = (elbow) => {
|
|
473
|
+
if (elbow.length !== 4) return false;
|
|
474
|
+
const [start, p1, p2, end] = elbow;
|
|
475
|
+
const startOrient = orientationOf(start, p1);
|
|
476
|
+
const startFacing = startOrient === "horizontal" ? p1.x > start.x ? "x+" : "x-" : p1.y > start.y ? "y+" : "y-";
|
|
477
|
+
const endOrient = orientationOf(p2, end);
|
|
478
|
+
const endFacing = endOrient === "horizontal" ? end.x > p2.x ? "x+" : "x-" : end.y > p2.y ? "y+" : "y-";
|
|
479
|
+
if (startFacing === "x+" && end.x < p1.x - EPS) return true;
|
|
480
|
+
if (startFacing === "x-" && end.x > p1.x + EPS) return true;
|
|
481
|
+
if (startFacing === "y+" && end.y < p1.y - EPS) return true;
|
|
482
|
+
if (startFacing === "y-" && end.y > p1.y + EPS) return true;
|
|
483
|
+
if (endFacing === "x-" && p2.x > end.x + EPS && startFacing === "x+")
|
|
484
|
+
return true;
|
|
485
|
+
if (endFacing === "x+" && p2.x < end.x - EPS && startFacing === "x-")
|
|
486
|
+
return true;
|
|
487
|
+
if (endFacing === "y-" && p2.y > end.y + EPS && startFacing === "y+")
|
|
488
|
+
return true;
|
|
489
|
+
if (endFacing === "y+" && p2.y < end.y - EPS && startFacing === "y-")
|
|
490
|
+
return true;
|
|
491
|
+
return false;
|
|
492
|
+
};
|
|
493
|
+
var expandToUTurn = (elbow) => {
|
|
494
|
+
if (elbow.length !== 4) return elbow;
|
|
495
|
+
const [start, p1, p2, end] = elbow;
|
|
496
|
+
const overshoot = Math.max(
|
|
497
|
+
Math.abs(start.x - p1.x),
|
|
498
|
+
Math.abs(start.y - p1.y),
|
|
499
|
+
0.2
|
|
500
|
+
// minimum overshoot
|
|
501
|
+
);
|
|
502
|
+
const startOrient = orientationOf(start, p1);
|
|
503
|
+
const expanded = [{ ...start }];
|
|
504
|
+
if (startOrient === "horizontal") {
|
|
505
|
+
const startDir = p1.x > start.x ? 1 : -1;
|
|
506
|
+
expanded.push({ x: start.x + startDir * overshoot, y: start.y });
|
|
507
|
+
const verticalSpace = Math.max(
|
|
508
|
+
overshoot * 2,
|
|
509
|
+
Math.abs(end.y - start.y) + overshoot
|
|
510
|
+
);
|
|
511
|
+
const midY = end.y > start.y ? start.y - verticalSpace : start.y + verticalSpace;
|
|
512
|
+
expanded.push({ x: start.x + startDir * overshoot, y: midY });
|
|
513
|
+
const endOrient = orientationOf(p2, end);
|
|
514
|
+
const endApproachX = endOrient === "horizontal" ? end.x > p2.x ? end.x - overshoot : end.x + overshoot : end.x;
|
|
515
|
+
expanded.push({ x: endApproachX, y: midY });
|
|
516
|
+
expanded.push({ x: endApproachX, y: end.y });
|
|
517
|
+
} else {
|
|
518
|
+
const startDir = p1.y > start.y ? 1 : -1;
|
|
519
|
+
expanded.push({ x: start.x, y: start.y + startDir * overshoot });
|
|
520
|
+
const horizontalSpace = Math.max(
|
|
521
|
+
overshoot * 2,
|
|
522
|
+
Math.abs(end.x - start.x) + overshoot
|
|
523
|
+
);
|
|
524
|
+
const midX = end.x > start.x ? start.x - horizontalSpace : start.x + horizontalSpace;
|
|
525
|
+
expanded.push({ x: midX, y: start.y + startDir * overshoot });
|
|
526
|
+
const endOrient = orientationOf(p2, end);
|
|
527
|
+
const endApproachY = endOrient === "vertical" ? end.y > p2.y ? end.y - overshoot : end.y + overshoot : end.y;
|
|
528
|
+
expanded.push({ x: midX, y: endApproachY });
|
|
529
|
+
expanded.push({ x: end.x, y: endApproachY });
|
|
530
|
+
}
|
|
531
|
+
expanded.push({ ...end });
|
|
532
|
+
return expanded;
|
|
533
|
+
};
|
|
472
534
|
var isAxisAligned = (a, b) => Math.abs(a.x - b.x) < EPS || Math.abs(a.y - b.y) < EPS;
|
|
473
535
|
var orientationOf = (a, b) => {
|
|
474
536
|
const dx = Math.abs(a.x - b.x);
|
|
@@ -550,15 +612,20 @@ var generateElbowVariants = ({
|
|
|
550
612
|
const elbow = preprocessElbow(baseElbow);
|
|
551
613
|
assertOrthogonalPolyline(elbow);
|
|
552
614
|
const nPts = elbow.length;
|
|
553
|
-
|
|
554
|
-
if (nSegs < 5) {
|
|
615
|
+
if (nPts < 4) {
|
|
555
616
|
return {
|
|
556
617
|
elbowVariants: [elbow.map((p) => ({ ...p }))],
|
|
557
618
|
movableSegments: []
|
|
558
619
|
};
|
|
620
|
+
} else if (nPts === 4) {
|
|
621
|
+
const needsUTurn = checkIfUTurnNeeded(elbow);
|
|
622
|
+
if (needsUTurn) {
|
|
623
|
+
const expandedElbow = expandToUTurn(elbow);
|
|
624
|
+
return generateElbowVariants({ baseElbow: expandedElbow, guidelines });
|
|
625
|
+
}
|
|
559
626
|
}
|
|
560
|
-
const firstMovableIndex =
|
|
561
|
-
const lastMovableIndex = nPts -
|
|
627
|
+
const firstMovableIndex = 1;
|
|
628
|
+
const lastMovableIndex = nPts - 3;
|
|
562
629
|
const movableSegments = [];
|
|
563
630
|
const movableIdx = [];
|
|
564
631
|
const axes = [];
|
|
@@ -14,6 +14,123 @@ export interface MovableSegment {
|
|
|
14
14
|
const EPS = 1e-6 // numeric tolerance for equality
|
|
15
15
|
const MIN_LEN = 1e-6 // forbid near-zero length segments (adjacent collapses)
|
|
16
16
|
|
|
17
|
+
const checkIfUTurnNeeded = (elbow: Point[]): boolean => {
|
|
18
|
+
if (elbow.length !== 4) return false
|
|
19
|
+
|
|
20
|
+
const [start, p1, p2, end] = elbow
|
|
21
|
+
|
|
22
|
+
// Determine facing directions from the path segments
|
|
23
|
+
const startOrient = orientationOf(start, p1)
|
|
24
|
+
const startFacing: FacingDirection =
|
|
25
|
+
startOrient === "horizontal"
|
|
26
|
+
? p1.x > start.x
|
|
27
|
+
? "x+"
|
|
28
|
+
: "x-"
|
|
29
|
+
: p1.y > start.y
|
|
30
|
+
? "y+"
|
|
31
|
+
: "y-"
|
|
32
|
+
|
|
33
|
+
const endOrient = orientationOf(p2, end)
|
|
34
|
+
const endFacing: FacingDirection =
|
|
35
|
+
endOrient === "horizontal"
|
|
36
|
+
? end.x > p2.x
|
|
37
|
+
? "x+"
|
|
38
|
+
: "x-"
|
|
39
|
+
: end.y > p2.y
|
|
40
|
+
? "y+"
|
|
41
|
+
: "y-"
|
|
42
|
+
|
|
43
|
+
// Check if path overshoots and needs to turn back
|
|
44
|
+
if (startFacing === "x+" && end.x < p1.x - EPS) return true
|
|
45
|
+
if (startFacing === "x-" && end.x > p1.x + EPS) return true
|
|
46
|
+
if (startFacing === "y+" && end.y < p1.y - EPS) return true
|
|
47
|
+
if (startFacing === "y-" && end.y > p1.y + EPS) return true
|
|
48
|
+
|
|
49
|
+
// Check if path segments conflict (p2 is past the end in the facing direction)
|
|
50
|
+
if (endFacing === "x-" && p2.x > end.x + EPS && startFacing === "x+")
|
|
51
|
+
return true
|
|
52
|
+
if (endFacing === "x+" && p2.x < end.x - EPS && startFacing === "x-")
|
|
53
|
+
return true
|
|
54
|
+
if (endFacing === "y-" && p2.y > end.y + EPS && startFacing === "y+")
|
|
55
|
+
return true
|
|
56
|
+
if (endFacing === "y+" && p2.y < end.y - EPS && startFacing === "y-")
|
|
57
|
+
return true
|
|
58
|
+
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const expandToUTurn = (elbow: Point[]): Point[] => {
|
|
63
|
+
if (elbow.length !== 4) return elbow
|
|
64
|
+
|
|
65
|
+
const [start, p1, p2, end] = elbow
|
|
66
|
+
|
|
67
|
+
// Calculate overshoot distance from existing segments
|
|
68
|
+
const overshoot = Math.max(
|
|
69
|
+
Math.abs(start.x - p1.x),
|
|
70
|
+
Math.abs(start.y - p1.y),
|
|
71
|
+
0.2, // minimum overshoot
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
const startOrient = orientationOf(start, p1)
|
|
75
|
+
const expanded: Point[] = [{ ...start }]
|
|
76
|
+
|
|
77
|
+
if (startOrient === "horizontal") {
|
|
78
|
+
const startDir = p1.x > start.x ? 1 : -1
|
|
79
|
+
expanded.push({ x: start.x + startDir * overshoot, y: start.y })
|
|
80
|
+
|
|
81
|
+
// Move away vertically to create space for U-turn
|
|
82
|
+
const verticalSpace = Math.max(
|
|
83
|
+
overshoot * 2,
|
|
84
|
+
Math.abs(end.y - start.y) + overshoot,
|
|
85
|
+
)
|
|
86
|
+
const midY =
|
|
87
|
+
end.y > start.y ? start.y - verticalSpace : start.y + verticalSpace
|
|
88
|
+
|
|
89
|
+
expanded.push({ x: start.x + startDir * overshoot, y: midY })
|
|
90
|
+
|
|
91
|
+
// Approach end from its required direction
|
|
92
|
+
const endOrient = orientationOf(p2, end)
|
|
93
|
+
const endApproachX =
|
|
94
|
+
endOrient === "horizontal"
|
|
95
|
+
? end.x > p2.x
|
|
96
|
+
? end.x - overshoot
|
|
97
|
+
: end.x + overshoot
|
|
98
|
+
: end.x
|
|
99
|
+
|
|
100
|
+
expanded.push({ x: endApproachX, y: midY })
|
|
101
|
+
expanded.push({ x: endApproachX, y: end.y })
|
|
102
|
+
} else {
|
|
103
|
+
// Vertical start
|
|
104
|
+
const startDir = p1.y > start.y ? 1 : -1
|
|
105
|
+
expanded.push({ x: start.x, y: start.y + startDir * overshoot })
|
|
106
|
+
|
|
107
|
+
// Move away horizontally to create space for U-turn
|
|
108
|
+
const horizontalSpace = Math.max(
|
|
109
|
+
overshoot * 2,
|
|
110
|
+
Math.abs(end.x - start.x) + overshoot,
|
|
111
|
+
)
|
|
112
|
+
const midX =
|
|
113
|
+
end.x > start.x ? start.x - horizontalSpace : start.x + horizontalSpace
|
|
114
|
+
|
|
115
|
+
expanded.push({ x: midX, y: start.y + startDir * overshoot })
|
|
116
|
+
|
|
117
|
+
// Approach end from its required direction
|
|
118
|
+
const endOrient = orientationOf(p2, end)
|
|
119
|
+
const endApproachY =
|
|
120
|
+
endOrient === "vertical"
|
|
121
|
+
? end.y > p2.y
|
|
122
|
+
? end.y - overshoot
|
|
123
|
+
: end.y + overshoot
|
|
124
|
+
: end.y
|
|
125
|
+
|
|
126
|
+
expanded.push({ x: midX, y: endApproachY })
|
|
127
|
+
expanded.push({ x: end.x, y: endApproachY })
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
expanded.push({ ...end })
|
|
131
|
+
return expanded
|
|
132
|
+
}
|
|
133
|
+
|
|
17
134
|
/** True if segment [a,b] is axis-aligned (horizontal or vertical). */
|
|
18
135
|
const isAxisAligned = (a: Point, b: Point): boolean =>
|
|
19
136
|
Math.abs(a.x - b.x) < EPS || Math.abs(a.y - b.y) < EPS
|
|
@@ -155,21 +272,27 @@ export const generateElbowVariants = ({
|
|
|
155
272
|
assertOrthogonalPolyline(elbow)
|
|
156
273
|
|
|
157
274
|
const nPts = elbow.length
|
|
158
|
-
const nSegs = nPts - 1
|
|
159
275
|
|
|
160
276
|
// No interior segments to move if path is too short.
|
|
161
|
-
if (
|
|
277
|
+
if (nPts < 4) {
|
|
162
278
|
return {
|
|
163
279
|
elbowVariants: [elbow.map((p) => ({ ...p }))],
|
|
164
280
|
movableSegments: [],
|
|
165
281
|
}
|
|
282
|
+
} else if (nPts === 4) {
|
|
283
|
+
const needsUTurn = checkIfUTurnNeeded(elbow)
|
|
284
|
+
if (needsUTurn) {
|
|
285
|
+
const expandedElbow = expandToUTurn(elbow)
|
|
286
|
+
// Recursively call with the expanded path
|
|
287
|
+
return generateElbowVariants({ baseElbow: expandedElbow, guidelines })
|
|
288
|
+
}
|
|
166
289
|
}
|
|
167
290
|
|
|
168
291
|
// 2) Choose which segments are allowed to move.
|
|
169
|
-
// We avoid
|
|
170
|
-
// movable indices i in [
|
|
171
|
-
const firstMovableIndex =
|
|
172
|
-
const lastMovableIndex = nPts -
|
|
292
|
+
// We avoid moving the very first and last segments of the:
|
|
293
|
+
// movable indices i in [1 .. (nPts - 3)] inclusive (segment i connects P[i] -> P[i+1]).
|
|
294
|
+
const firstMovableIndex = 1
|
|
295
|
+
const lastMovableIndex = nPts - 3
|
|
173
296
|
|
|
174
297
|
const movableSegments: MovableSegment[] = []
|
|
175
298
|
const movableIdx: number[] = []
|
package/package.json
CHANGED
|
@@ -2,100 +2,97 @@
|
|
|
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="-0.8" data-y="0.2" cx="422.5742574257426" cy="
|
|
5
|
+
x-" data-x="-0.8" data-y="0.2" cx="422.5742574257426" cy="272.8712871287128" 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="-0.8" data-y="0" cx="422.5742574257426" cy="
|
|
9
|
+
x-" data-x="-0.8" data-y="0" cx="422.5742574257426" cy="295.049504950495" 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="-0.8" data-y="-0.2" cx="422.5742574257426" cy="
|
|
13
|
+
x-" data-x="-0.8" data-y="-0.2" cx="422.5742574257426" cy="317.2277227722772" 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="0.8" data-y="-0.2" cx="600" cy="
|
|
17
|
+
x+" data-x="0.8" data-y="-0.2" cx="600" cy="317.2277227722772" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
|
|
18
18
|
</g>
|
|
19
19
|
<g>
|
|
20
20
|
<circle data-type="point" data-label="U1.5
|
|
21
|
-
x+" data-x="0.8" data-y="0" cx="600" cy="
|
|
21
|
+
x+" data-x="0.8" data-y="0" cx="600" cy="295.049504950495" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
|
|
22
22
|
</g>
|
|
23
23
|
<g>
|
|
24
24
|
<circle data-type="point" data-label="U1.6
|
|
25
|
-
x+" data-x="0.8" data-y="0.2" cx="600" cy="
|
|
25
|
+
x+" data-x="0.8" data-y="0.2" cx="600" cy="272.8712871287128" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
|
|
26
26
|
</g>
|
|
27
27
|
<g>
|
|
28
28
|
<circle data-type="point" data-label="C1.1
|
|
29
|
-
y+" data-x="-2" data-y="0.5" cx="289.50495049504957" cy="
|
|
29
|
+
y+" data-x="-2" data-y="0.5" cx="289.50495049504957" cy="239.60396039603958" r="3" fill="hsl(121, 100%, 50%, 0.8)" />
|
|
30
30
|
</g>
|
|
31
31
|
<g>
|
|
32
32
|
<circle data-type="point" data-label="C1.2
|
|
33
|
-
y-" data-x="-2" data-y="-0.5" cx="289.50495049504957" cy="
|
|
33
|
+
y-" data-x="-2" data-y="-0.5" cx="289.50495049504957" cy="350.4950495049505" r="3" fill="hsl(122, 100%, 50%, 0.8)" />
|
|
34
34
|
</g>
|
|
35
35
|
<g>
|
|
36
36
|
<circle data-type="point" data-label="C2.1
|
|
37
|
-
y+" data-x="-4" data-y="0.5" cx="67.72277227722776" cy="
|
|
37
|
+
y+" data-x="-4" data-y="0.5" cx="67.72277227722776" cy="239.60396039603958" r="3" fill="hsl(2, 100%, 50%, 0.8)" />
|
|
38
38
|
</g>
|
|
39
39
|
<g>
|
|
40
40
|
<circle data-type="point" data-label="C2.2
|
|
41
|
-
y-" data-x="-4" data-y="-0.5" cx="67.72277227722776" cy="
|
|
41
|
+
y-" data-x="-4" data-y="-0.5" cx="67.72277227722776" cy="350.4950495049505" r="3" fill="hsl(3, 100%, 50%, 0.8)" />
|
|
42
42
|
</g>
|
|
43
43
|
<g>
|
|
44
|
-
<circle data-type="point" data-label="" data-x="-1.
|
|
44
|
+
<circle data-type="point" data-label="" data-x="-1.1" data-y="0.20000000000000018" cx="389.3069306930693" cy="272.8712871287128" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
45
45
|
</g>
|
|
46
46
|
<g>
|
|
47
|
-
<circle data-type="point" data-label="" data-x="-
|
|
47
|
+
<circle data-type="point" data-label="" data-x="-1.275" data-y="0" cx="369.90099009900996" cy="295.049504950495" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
48
48
|
</g>
|
|
49
49
|
<g>
|
|
50
|
-
<circle data-type="point" data-label="" data-x="-4" data-y="0.
|
|
50
|
+
<circle data-type="point" data-label="" data-x="-4" data-y="-0.7000000000000002" cx="67.72277227722776" cy="372.6732673267327" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
51
51
|
</g>
|
|
52
52
|
<g>
|
|
53
|
-
<
|
|
53
|
+
<polyline data-points="-0.8,0.2 -2,0.5" data-type="line" data-label="" points="422.5742574257426,272.8712871287128 289.50495049504957,239.60396039603958" fill="none" stroke="hsl(190, 100%, 50%, 0.8)" stroke-width="1" />
|
|
54
54
|
</g>
|
|
55
55
|
<g>
|
|
56
|
-
<polyline data-points="-0.8,0
|
|
56
|
+
<polyline data-points="-0.8,0 -4,0.5" data-type="line" data-label="" points="422.5742574257426,295.049504950495 67.72277227722776,239.60396039603958" fill="none" stroke="hsl(57, 100%, 50%, 0.8)" stroke-width="1" />
|
|
57
57
|
</g>
|
|
58
58
|
<g>
|
|
59
|
-
<polyline data-points="-0.8
|
|
59
|
+
<polyline data-points="-0.8,-0.2 -4,-0.5" data-type="line" data-label="" points="422.5742574257426,317.2277227722772 67.72277227722776,350.4950495049505" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
60
60
|
</g>
|
|
61
61
|
<g>
|
|
62
|
-
<polyline data-points="-0.8,-0.2 -
|
|
62
|
+
<polyline data-points="-0.8,-0.2 -2,-0.5" data-type="line" data-label="" points="422.5742574257426,317.2277227722772 289.50495049504957,350.4950495049505" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
63
63
|
</g>
|
|
64
64
|
<g>
|
|
65
|
-
<polyline data-points="-
|
|
65
|
+
<polyline data-points="-4,-0.5 -2,-0.5" data-type="line" data-label="" points="67.72277227722776,350.4950495049505 289.50495049504957,350.4950495049505" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
66
66
|
</g>
|
|
67
67
|
<g>
|
|
68
|
-
<polyline data-points="-4
|
|
68
|
+
<polyline data-points="-0.8,0.20000000000000018 -1.4,0.20000000000000018 -1.4,0.5 -2,0.5" data-type="line" data-label="" points="422.5742574257426,272.8712871287128 356.0396039603961,272.8712871287128 356.0396039603961,239.60396039603958 289.50495049504957,239.60396039603958" fill="none" stroke="purple" stroke-width="1" />
|
|
69
69
|
</g>
|
|
70
70
|
<g>
|
|
71
|
-
<polyline data-points="-0.
|
|
71
|
+
<polyline data-points="-0.7999999999999998,0 -1.275,0 -1.275,0.7 -4,0.7 -4,0.5" data-type="line" data-label="" points="422.57425742574264,295.049504950495 369.90099009900996,295.049504950495 369.90099009900996,217.4257425742574 67.72277227722776,217.4257425742574 67.72277227722776,239.60396039603958" fill="none" stroke="purple" stroke-width="1" />
|
|
72
72
|
</g>
|
|
73
73
|
<g>
|
|
74
|
-
<polyline data-points="-0.8,-0.20000000000000018 -1.4,-0.20000000000000018 -1.4,-0.
|
|
74
|
+
<polyline data-points="-0.8,-0.20000000000000018 -1.4,-0.20000000000000018 -1.4,-0.6 -2,-0.6 -2,-0.5" data-type="line" data-label="" points="422.5742574257426,317.2277227722772 356.0396039603961,317.2277227722772 356.0396039603961,361.58415841584156 289.50495049504957,361.58415841584156 289.50495049504957,350.4950495049505" fill="none" stroke="purple" stroke-width="1" />
|
|
75
75
|
</g>
|
|
76
76
|
<g>
|
|
77
|
-
<polyline data-points="-4,-0.5 -4,-0.7000000000000002 -2,-0.7000000000000002 -2,-0.5" data-type="line" data-label="" points="67.72277227722776,
|
|
77
|
+
<polyline data-points="-4,-0.5 -4,-0.7000000000000002 -2,-0.7000000000000002 -2,-0.5" data-type="line" data-label="" points="67.72277227722776,350.4950495049505 67.72277227722776,372.6732673267327 289.50495049504957,372.6732673267327 289.50495049504957,350.4950495049505" fill="none" stroke="purple" stroke-width="1" />
|
|
78
78
|
</g>
|
|
79
79
|
<g>
|
|
80
|
-
<rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="422.5742574257426" y="
|
|
80
|
+
<rect data-type="rect" data-label="U1" data-x="0" data-y="0" x="422.5742574257426" y="261.78217821782175" width="177.4257425742574" height="66.53465346534654" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009017857142857143" />
|
|
81
81
|
</g>
|
|
82
82
|
<g>
|
|
83
|
-
<rect data-type="rect" data-label="C1" data-x="-2" data-y="0" x="261.7821782178218" y="
|
|
83
|
+
<rect data-type="rect" data-label="C1" data-x="-2" data-y="0" x="261.7821782178218" y="239.60396039603958" width="55.445544554455466" height="110.8910891089109" fill="hsl(326, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009017857142857143" />
|
|
84
84
|
</g>
|
|
85
85
|
<g>
|
|
86
|
-
<rect data-type="rect" data-label="C2" data-x="-4" data-y="0" x="40.00000000000006" y="
|
|
86
|
+
<rect data-type="rect" data-label="C2" data-x="-4" data-y="0" x="40.00000000000006" y="239.60396039603958" width="55.44554455445541" height="110.8910891089109" fill="hsl(327, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009017857142857143" />
|
|
87
87
|
</g>
|
|
88
88
|
<g>
|
|
89
|
-
<rect data-type="rect" data-label="" data-x="-1.
|
|
89
|
+
<rect data-type="rect" data-label="" data-x="-1.1" data-y="0.42500000000000016" x="378.21782178217825" y="222.97029702970292" width="22.178217821782198" height="49.9009900990099" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
|
|
90
90
|
</g>
|
|
91
91
|
<g>
|
|
92
|
-
<rect data-type="rect" data-label="" data-x="-1.
|
|
92
|
+
<rect data-type="rect" data-label="" data-x="-1.5" data-y="0" x="320" y="283.96039603960395" width="49.90099009900996" height="22.17821782178214" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
|
|
93
93
|
</g>
|
|
94
94
|
<g>
|
|
95
|
-
<rect data-type="rect" data-label="" data-x="-4" data-y="0.
|
|
96
|
-
</g>
|
|
97
|
-
<g>
|
|
98
|
-
<rect data-type="rect" data-label="" data-x="-1.4" data-y="-0.9249999999999999" x="344.950495049505" y="397.6237623762376" width="22.178217821782198" height="49.9009900990099" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
|
|
95
|
+
<rect data-type="rect" data-label="" data-x="-4" data-y="-0.9250000000000002" x="56.63366336633669" y="372.6732673267327" width="22.17821782178214" height="49.900990099009846" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
|
|
99
96
|
</g>
|
|
100
97
|
<g id="crosshair" style="display: none">
|
|
101
98
|
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
@@ -130,7 +127,7 @@ y-" data-x="-4" data-y="-0.5" cx="67.72277227722776" cy="375.44554455445547" r="
|
|
|
130
127
|
"e": 511.2871287128713,
|
|
131
128
|
"b": 0,
|
|
132
129
|
"d": -110.89108910891089,
|
|
133
|
-
"f":
|
|
130
|
+
"f": 295.049504950495
|
|
134
131
|
};
|
|
135
132
|
// Manually invert and apply the affine transform
|
|
136
133
|
// Since we only use translate and scale, we can directly compute:
|
|
@@ -53,7 +53,7 @@ x+" data-x="1" data-y="-0.1" cx="500.20151295522464" cy="341.11637364700744" r="
|
|
|
53
53
|
x+" data-x="1" data-y="0.1" cx="500.20151295522464" cy="324.189420823755" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
|
|
54
54
|
</g>
|
|
55
55
|
<g>
|
|
56
|
-
<circle data-type="point" data-label="" data-x="-
|
|
56
|
+
<circle data-type="point" data-label="" data-x="-3.0440232499999995" data-y="1.3024186000000004" cx="157.93655911079327" cy="222.4230062437483" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
57
57
|
</g>
|
|
58
58
|
<g>
|
|
59
59
|
<circle data-type="point" data-label="" data-x="-3.0434765500000003" data-y="-0.2000000000000004" cx="157.98282893633558" cy="349.5798500586337" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
@@ -158,10 +158,10 @@ x+" data-x="1" data-y="0.1" cx="500.20151295522464" cy="324.189420823755" r="3"
|
|
|
158
158
|
<polyline data-points="-1.9148566499999995,1.1024186000000002 -1.9148566499999995,1.3024186000000004 -3.0440232499999995,1.3024186000000004 -3.0440232499999995,1.1024186000000002" data-type="line" data-label="" points="253.50330794975545,239.3499590670008 253.50330794975545,222.4230062437483 157.93655911079327,222.4230062437483 157.93655911079327,239.3499590670008" fill="none" stroke="purple" stroke-width="1" />
|
|
159
159
|
</g>
|
|
160
160
|
<g>
|
|
161
|
-
<polyline data-points="-1,0.20000000000000018 -1.4574283249999997,0.20000000000000018 -1.4574283249999997,1.
|
|
161
|
+
<polyline data-points="-1,0.20000000000000018 -1.4574283249999997,0.20000000000000018 -1.4574283249999997,1.2024186000000006 -1.9148566499999995,1.2024186000000006 -1.9148566499999995,1.1024186000000005" data-type="line" data-label="" points="330.93198472269955,315.7259444121287 292.2176463362275,315.7259444121287 292.2176463362275,230.88648265537452 253.50330794975545,230.88648265537452 253.50330794975545,239.34995906700078" fill="none" stroke="purple" stroke-width="1" />
|
|
162
162
|
</g>
|
|
163
163
|
<g>
|
|
164
|
-
<polyline data-points="-1,-0.2 -1.
|
|
164
|
+
<polyline data-points="-1,-0.2 -1.2,-0.2 -1.2,0.2 -1,0.2" data-type="line" data-label="" points="330.93198472269955,349.5798500586337 314.0050318994471,349.5798500586337 314.0050318994471,315.7259444121287 330.93198472269955,315.7259444121287" fill="none" stroke="purple" stroke-width="1" />
|
|
165
165
|
</g>
|
|
166
166
|
<g>
|
|
167
167
|
<polyline data-points="-3.0434765500000003,-2.220446049250313e-16 -3.0434765500000003,-0.2000000000000004 -4.17264315,-0.2000000000000004 -4.17264315,-2.220446049250313e-16" data-type="line" data-label="" points="157.98282893633558,332.6528972353812 157.98282893633558,349.5798500586337 62.41608009737348,349.5798500586337 62.41608009737348,332.6528972353812" fill="none" stroke="purple" stroke-width="1" />
|
|
@@ -170,7 +170,7 @@ x+" data-x="1" data-y="0.1" cx="500.20151295522464" cy="324.189420823755" r="3"
|
|
|
170
170
|
<polyline data-points="-1.9143099500000003,-2.220446049250313e-16 -1.9143099500000003,-0.2000000000000004 -3.0434765500000003,-0.2000000000000004 -3.0434765500000003,-2.220446049250313e-16" data-type="line" data-label="" points="253.54957777529776,332.6528972353812 253.54957777529776,349.5798500586337 157.98282893633558,349.5798500586337 157.98282893633558,332.6528972353812" fill="none" stroke="purple" stroke-width="1" />
|
|
171
171
|
</g>
|
|
172
172
|
<g>
|
|
173
|
-
<polyline data-points="-1,0 -1.
|
|
173
|
+
<polyline data-points="-1,0 -1.325,0 -1.325,-0.1500000000000002 -1.9143099500000003,-0.1500000000000002 -1.9143099500000003,0" data-type="line" data-label="" points="330.93198472269955,332.6528972353812 303.42568638491423,332.6528972353812 303.42568638491423,345.3481118528206 253.54957777529776,345.3481118528206 253.54957777529776,332.6528972353812" fill="none" stroke="purple" stroke-width="1" />
|
|
174
174
|
</g>
|
|
175
175
|
<g>
|
|
176
176
|
<polyline data-points="1,0.1 1.9143099500000003,0.1" data-type="line" data-label="" points="500.20151295522464,324.189420823755 577.5839199026265,324.189420823755" fill="none" stroke="purple" stroke-width="1" />
|
|
@@ -191,7 +191,7 @@ x+" data-x="1" data-y="0.1" cx="500.20151295522464" cy="324.189420823755" r="3"
|
|
|
191
191
|
<rect data-type="rect" data-label="schematic_component_4" data-x="0" data-y="0" x="330.93198472269955" y="298.7989915888762" width="169.2695282325251" height="67.70781129300997" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.011815475714285715" />
|
|
192
192
|
</g>
|
|
193
193
|
<g>
|
|
194
|
-
<rect data-type="rect" data-label="" data-x="-
|
|
194
|
+
<rect data-type="rect" data-label="" data-x="-3.0440232499999995" data-y="1.5274186000000005" x="149.47308269916704" y="184.33736239143013" width="16.92695282325252" height="38.08564385231816" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011815475714285715" />
|
|
195
195
|
</g>
|
|
196
196
|
<g>
|
|
197
197
|
<rect data-type="rect" data-label="" data-x="-3.0434765500000003" data-y="-0.4250000000000004" x="149.51935252470935" y="349.5798500586337" width="16.926952823252492" height="38.085643852318185" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011815475714285715" />
|
|
@@ -2,30 +2,30 @@
|
|
|
2
2
|
<rect width="100%" height="100%" fill="white" />
|
|
3
3
|
<g>
|
|
4
4
|
<circle data-type="point" data-label="Q1.1
|
|
5
|
-
y+" data-x="0.30397715550000004" data-y="0.5800832909999993" cx="
|
|
5
|
+
y+" data-x="0.30397715550000004" data-y="0.5800832909999993" cx="398.5713361931903" cy="210.15008622007596" r="3" fill="hsl(315, 100%, 50%, 0.8)" />
|
|
6
6
|
</g>
|
|
7
7
|
<g>
|
|
8
8
|
<circle data-type="point" data-label="Q1.2
|
|
9
|
-
y-" data-x="0.31067575550000137" data-y="-0.5800832909999993" cx="
|
|
9
|
+
y-" data-x="0.31067575550000137" data-y="-0.5800832909999993" cx="400.643640497834" cy="569.0636206872589" r="3" fill="hsl(316, 100%, 50%, 0.8)" />
|
|
10
10
|
</g>
|
|
11
11
|
<g>
|
|
12
12
|
<circle data-type="point" data-label="Q1.3
|
|
13
|
-
x-" data-x="-0.4467558855000001" data-y="-0.10250625000000019" cx="
|
|
13
|
+
x-" data-x="-0.4467558855000001" data-y="-0.10250625000000019" cx="166.32171500335414" cy="421.31857577293414" r="3" fill="hsl(317, 100%, 50%, 0.8)" />
|
|
14
14
|
</g>
|
|
15
15
|
<g>
|
|
16
|
-
<circle data-type="point" data-label="" data-x="0.30397715550000004" data-y="0.
|
|
16
|
+
<circle data-type="point" data-label="" data-x="0.30397715550000004" data-y="0.6800832909999993" cx="398.5713361931903" cy="179.21370690733488" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
|
|
17
17
|
</g>
|
|
18
18
|
<g>
|
|
19
|
-
<polyline data-points="0.30397715550000004,0.5800832909999993 0.31067575550000137,-0.5800832909999993" data-type="line" data-label="" points="
|
|
19
|
+
<polyline data-points="0.30397715550000004,0.5800832909999993 0.31067575550000137,-0.5800832909999993" data-type="line" data-label="" points="398.5713361931903,210.15008622007596 400.643640497834,569.0636206872589" fill="none" stroke="hsl(73, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
|
|
20
20
|
</g>
|
|
21
21
|
<g>
|
|
22
|
-
<polyline data-points="0.30397715550000004,0.5800832909999993 0.30397715550000004,0.
|
|
22
|
+
<polyline data-points="0.30397715550000004,0.5800832909999993 0.30397715550000004,0.6800832909999993 0.5467558855000001,0.6800832909999993 0.5467558855000001,-0.6800832909999993 0.31067575550000137,-0.6800832909999993 0.31067575550000137,-0.5800832909999993" data-type="line" data-label="" points="398.5713361931903,210.15008622007596 398.5713361931903,179.21370690733488 473.67828499664586,179.21370690733488 473.67828499664586,600 400.643640497834,600 400.643640497834,569.0636206872589" fill="none" stroke="purple" stroke-width="1" />
|
|
23
23
|
</g>
|
|
24
24
|
<g>
|
|
25
|
-
<rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="
|
|
25
|
+
<rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="166.32171500335414" y="210.15008622007596" width="276.4201906805506" height="358.9135344671829" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.0032324403249999975" />
|
|
26
26
|
</g>
|
|
27
27
|
<g>
|
|
28
|
-
<rect data-type="rect" data-label="" data-x="0.30397715550000004" data-y="
|
|
28
|
+
<rect data-type="rect" data-label="" data-x="0.30397715550000004" data-y="0.9050832909999993" x="367.6349568804492" y="40" width="61.87275862548216" height="139.21370690733488" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.0032324403249999975" />
|
|
29
29
|
</g>
|
|
30
30
|
<g id="crosshair" style="display: none">
|
|
31
31
|
<line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
|
|
@@ -55,12 +55,12 @@ x-" data-x="-0.4467558855000001" data-y="-0.10250625000000019" cx="181.611819452
|
|
|
55
55
|
|
|
56
56
|
// Calculate real coordinates using inverse transformation
|
|
57
57
|
const matrix = {
|
|
58
|
-
"a":
|
|
58
|
+
"a": 309.3637931274109,
|
|
59
59
|
"c": 0,
|
|
60
|
-
"e":
|
|
60
|
+
"e": 304.53181034362945,
|
|
61
61
|
"b": 0,
|
|
62
|
-
"d": -
|
|
63
|
-
"f":
|
|
62
|
+
"d": -309.3637931274109,
|
|
63
|
+
"f": 389.60685345366744
|
|
64
64
|
};
|
|
65
65
|
// Manually invert and apply the affine transform
|
|
66
66
|
// Since we only use translate and scale, we can directly compute:
|