@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 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
- const nSegs = nPts - 1;
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 = 2;
561
- const lastMovableIndex = nPts - 4;
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 (nSegs < 5) {
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 segments adjacent to the first and last segment:
170
- // movable indices i in [2 .. (nPts - 4)] inclusive (segment i connects P[i] -> P[i+1]).
171
- const firstMovableIndex = 2
172
- const lastMovableIndex = nPts - 4
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-trace-solver",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.28",
4
+ "version": "0.0.29",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -88,7 +88,7 @@ export const inputProblem: InputProblem = {
88
88
  ],
89
89
  netConnections: [],
90
90
  availableNetLabelOrientations: {},
91
- maxMspPairDistance: 2,
91
+ maxMspPairDistance: 5,
92
92
  }
93
93
 
94
94
  export default () => <PipelineDebugger inputProblem={inputProblem} />
@@ -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="297.8217821782178" r="3" fill="hsl(319, 100%, 50%, 0.8)" />
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="320" r="3" fill="hsl(320, 100%, 50%, 0.8)" />
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="342.1782178217822" r="3" fill="hsl(321, 100%, 50%, 0.8)" />
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="342.1782178217822" r="3" fill="hsl(322, 100%, 50%, 0.8)" />
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="320" r="3" fill="hsl(323, 100%, 50%, 0.8)" />
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="297.8217821782178" r="3" fill="hsl(324, 100%, 50%, 0.8)" />
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="264.55445544554453" r="3" fill="hsl(121, 100%, 50%, 0.8)" />
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="375.44554455445547" r="3" fill="hsl(122, 100%, 50%, 0.8)" />
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="264.55445544554453" r="3" fill="hsl(2, 100%, 50%, 0.8)" />
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="375.44554455445547" r="3" fill="hsl(3, 100%, 50%, 0.8)" />
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.4" data-y="0.7" cx="356.0396039603961" cy="242.3762376237624" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
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="-0.8" data-y="0" cx="422.5742574257426" cy="320" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
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.5" cx="67.72277227722776" cy="264.55445544554453" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
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
- <circle data-type="point" data-label="" data-x="-1.4" data-y="-0.7" cx="356.0396039603961" cy="397.6237623762376" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
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.2 -2,0.5" data-type="line" data-label="" points="422.5742574257426,297.8217821782178 289.50495049504957,264.55445544554453" fill="none" stroke="hsl(190, 100%, 50%, 0.8)" stroke-width="1" />
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,0 -4,0.5" data-type="line" data-label="" points="422.5742574257426,320 67.72277227722776,264.55445544554453" fill="none" stroke="hsl(57, 100%, 50%, 0.8)" stroke-width="1" />
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 -4,-0.5" data-type="line" data-label="" points="422.5742574257426,342.1782178217822 67.72277227722776,375.44554455445547" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 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="-0.8,-0.2 -2,-0.5" data-type="line" data-label="" points="422.5742574257426,342.1782178217822 289.50495049504957,375.44554455445547" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
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,-0.5 -2,-0.5" data-type="line" data-label="" points="67.72277227722776,375.44554455445547 289.50495049504957,375.44554455445547" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
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.8,0.20000000000000018 -1.4,0.20000000000000018 -1.4,0.7 -2,0.7 -2,0.5" data-type="line" data-label="" points="422.5742574257426,297.8217821782178 356.0396039603961,297.8217821782178 356.0396039603961,242.3762376237624 289.50495049504957,242.3762376237624 289.50495049504957,264.55445544554453" fill="none" stroke="purple" stroke-width="1" />
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.7 -2,-0.7 -2,-0.5" data-type="line" data-label="" points="422.5742574257426,342.1782178217822 356.0396039603961,342.1782178217822 356.0396039603961,397.6237623762376 289.50495049504957,397.6237623762376 289.50495049504957,375.44554455445547" fill="none" stroke="purple" stroke-width="1" />
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,375.44554455445547 67.72277227722776,397.62376237623766 289.50495049504957,397.62376237623766 289.50495049504957,375.44554455445547" fill="none" stroke="purple" stroke-width="1" />
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="286.73267326732673" width="177.4257425742574" height="66.53465346534654" fill="hsl(164, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009017857142857143" />
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="264.55445544554453" width="55.445544554455466" height="110.89108910891093" fill="hsl(326, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009017857142857143" />
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="264.55445544554453" width="55.44554455445541" height="110.89108910891093" fill="hsl(327, 100%, 50%, 0.8)" stroke="black" stroke-width="0.009017857142857143" />
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.4" data-y="0.9249999999999999" x="344.950495049505" y="192.4752475247525" width="22.178217821782198" height="49.9009900990099" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
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.026" data-y="0" x="372.56237623762377" y="308.91089108910893" width="49.90099009900996" height="22.17821782178214" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
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.726" x="56.63366336633669" y="214.54257425742574" width="22.17821782178214" height="49.90099009900993" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.009017857142857143" />
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": 320
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="-1.4574283249999997" data-y="1.3024186000000004" cx="292.2176463362275" cy="222.4230062437483" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
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.3024186000000004 -1.9148566499999995,1.3024186000000004 -1.9148566499999995,1.1024186000000005" data-type="line" data-label="" points="330.93198472269955,315.7259444121287 292.2176463362275,315.7259444121287 292.2176463362275,222.4230062437483 253.50330794975545,222.4230062437483 253.50330794975545,239.34995906700078" fill="none" stroke="purple" stroke-width="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.3,-0.2 -1.3,0.2 -1,0.2" data-type="line" data-label="" points="330.93198472269955,349.5798500586337 305.5415554878208,349.5798500586337 305.5415554878208,315.7259444121287 330.93198472269955,315.7259444121287" fill="none" stroke="purple" stroke-width="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.0999999999999999,0 -1.0999999999999999,-0.09999999999999995 -1.9143099500000003,-0.09999999999999995 -1.9143099500000003,0" data-type="line" data-label="" points="330.93198472269955,332.6528972353812 322.4685083110733,332.6528972353812 322.4685083110733,341.11637364700744 253.54957777529776,341.11637364700744 253.54957777529776,332.6528972353812" fill="none" stroke="purple" stroke-width="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="-1.4574283249999997" data-y="1.5274186000000005" x="283.75416992460123" y="184.33736239143013" width="16.926952823252577" height="38.08564385231816" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.011815475714285715" />
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="390.7539406701768" cy="221.0795201051653" r="3" fill="hsl(315, 100%, 50%, 0.8)" />
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="392.6200626292179" cy="544.283224583026" r="3" fill="hsl(316, 100%, 50%, 0.8)" />
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="181.61181945268248" cy="411.2379608945266" r="3" fill="hsl(317, 100%, 50%, 0.8)" />
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.7800832909999994" cx="390.7539406701768" cy="165.36274468819138" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
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="390.7539406701768,221.0795201051653 392.6200626292179,544.283224583026" fill="none" stroke="hsl(73, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
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.7800832909999994 0.5467558855000001,0.7800832909999994 0.5467558855000001,-0.7800832909999995 0.31067575550000137,-0.7800832909999995 0.31067575550000137,-0.5800832909999993" data-type="line" data-label="" points="390.7539406701768,221.0795201051653 390.7539406701768,165.36274468819138 458.3881805473175,165.36274468819138 458.3881805473175,600 392.6200626292179,600 392.6200626292179,544.283224583026" fill="none" stroke="purple" stroke-width="1" />
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="181.61181945268248" y="221.0795201051653" width="248.9179733861481" height="323.2037044778607" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.003589583182142856" />
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="1.0050832909999994" x="362.8955529616899" y="40.000000000000114" width="55.71677541697386" height="125.36274468819127" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.003589583182142856" />
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": 278.58387708486947,
58
+ "a": 309.3637931274109,
59
59
  "c": 0,
60
- "e": 306.07080614575653,
60
+ "e": 304.53181034362945,
61
61
  "b": 0,
62
- "d": -278.58387708486947,
63
- "f": 382.6813723440957
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: