@tscircuit/schematic-trace-solver 0.0.36 → 0.0.37

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
@@ -776,10 +776,17 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
776
776
  return;
777
777
  }
778
778
  const { path, collisionChipIds } = state;
779
+ const [PA, PB] = this.pins;
779
780
  const collision = findFirstCollision(path, this.obstacles);
780
781
  if (!collision) {
781
- this.solvedTracePath = path;
782
- this.solved = true;
782
+ const first = path[0];
783
+ const last = path[path.length - 1];
784
+ const EPS4 = 1e-9;
785
+ const samePoint = (p, q) => Math.abs(p.x - q.x) < EPS4 && Math.abs(p.y - q.y) < EPS4;
786
+ if (samePoint(first, { x: PA.x, y: PA.y }) && samePoint(last, { x: PB.x, y: PB.y })) {
787
+ this.solvedTracePath = path;
788
+ this.solved = true;
789
+ }
783
790
  return;
784
791
  }
785
792
  let { segIndex, rect } = collision;
@@ -802,7 +809,6 @@ var SchematicTraceSingleLineSolver2 = class extends BaseSolver {
802
809
  if (!axis) {
803
810
  return;
804
811
  }
805
- const [PA, PB] = this.pins;
806
812
  const candidates = [];
807
813
  if (collisionChipIds.size === 0) {
808
814
  const m1 = midBetweenPointAndRect(axis, { x: PA.x, y: PA.y }, rect);
@@ -129,11 +129,23 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
129
129
 
130
130
  const { path, collisionChipIds } = state
131
131
 
132
+ const [PA, PB] = this.pins
132
133
  const collision = findFirstCollision(path, this.obstacles)
133
134
 
134
135
  if (!collision) {
135
- this.solvedTracePath = path
136
- this.solved = true
136
+ // Sanity check: ensure path still connects PA -> PB
137
+ const first = path[0]!
138
+ const last = path[path.length - 1]!
139
+ const EPS = 1e-9
140
+ const samePoint = (p: Point, q: Point) =>
141
+ Math.abs(p.x - q.x) < EPS && Math.abs(p.y - q.y) < EPS
142
+ if (
143
+ samePoint(first, { x: PA.x, y: PA.y }) &&
144
+ samePoint(last, { x: PB.x, y: PB.y })
145
+ ) {
146
+ this.solvedTracePath = path
147
+ this.solved = true
148
+ }
137
149
  return
138
150
  }
139
151
 
@@ -167,7 +179,7 @@ export class SchematicTraceSingleLineSolver2 extends BaseSolver {
167
179
  return
168
180
  }
169
181
 
170
- const [PA, PB] = this.pins
182
+ // Note: PA and PB are already defined above
171
183
  const candidates: number[] = []
172
184
 
173
185
  if (collisionChipIds.size === 0) {
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.36",
4
+ "version": "0.0.37",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "start": "cosmos",
@@ -0,0 +1,177 @@
1
+ import { PipelineDebugger } from "site/components/PipelineDebugger"
2
+ import type { InputProblem } from "lib/types/InputProblem"
3
+
4
+ const inputProblem: InputProblem = {
5
+ chips: [
6
+ {
7
+ chipId: "schematic_component_0",
8
+ center: {
9
+ x: 0,
10
+ y: 0,
11
+ },
12
+ width: 2,
13
+ height: 2,
14
+ pins: [
15
+ {
16
+ pinId: "CORNERS.1",
17
+ x: -1.4,
18
+ y: -0.6,
19
+ },
20
+ {
21
+ pinId: "CORNERS.2",
22
+ x: -1.4,
23
+ y: 0.6,
24
+ },
25
+ {
26
+ pinId: "CORNERS.3",
27
+ x: 1.4,
28
+ y: 0.6,
29
+ },
30
+ {
31
+ pinId: "CORNERS.4",
32
+ x: 1.4,
33
+ y: -0.6,
34
+ },
35
+ ],
36
+ },
37
+ {
38
+ chipId: "schematic_component_1",
39
+ center: {
40
+ x: 4.785,
41
+ y: -0.3999999999999999,
42
+ },
43
+ width: 1.2000000000000002,
44
+ height: 1,
45
+ pins: [
46
+ {
47
+ pinId: "U100.1",
48
+ x: 3.785,
49
+ y: -0.29999999999999993,
50
+ },
51
+ {
52
+ pinId: "U100.2",
53
+ x: 4.785,
54
+ y: -1.2999999999999998,
55
+ },
56
+ {
57
+ pinId: "U100.3",
58
+ x: 3.785,
59
+ y: -0.4999999999999999,
60
+ },
61
+ {
62
+ pinId: "U100.5",
63
+ x: 5.785,
64
+ y: -0.3999999999999999,
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ chipId: "schematic_component_2",
70
+ center: {
71
+ x: 6.7,
72
+ y: -0.9499999999999993,
73
+ },
74
+ width: 0.53,
75
+ height: 1.06,
76
+ pins: [
77
+ {
78
+ pinId: "C101.1",
79
+ x: 6.7,
80
+ y: -0.39999999999999925,
81
+ },
82
+ {
83
+ pinId: "C101.2",
84
+ x: 6.7,
85
+ y: -1.4999999999999993,
86
+ },
87
+ ],
88
+ },
89
+ {
90
+ chipId: "schematic_component_3",
91
+ center: {
92
+ x: 2.8699999999999997,
93
+ y: -1.75,
94
+ },
95
+ width: 0.53,
96
+ height: 1.06,
97
+ pins: [
98
+ {
99
+ pinId: "C100.1",
100
+ x: 2.8699999999999997,
101
+ y: -1.2,
102
+ },
103
+ {
104
+ pinId: "C100.2",
105
+ x: 2.8699999999999997,
106
+ y: -2.3,
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ chipId: "schematic_component_4",
112
+ center: {
113
+ x: 2.9752723250000006,
114
+ y: 0.050000000000000266,
115
+ },
116
+ width: 0.3194553499999995,
117
+ height: 1.06,
118
+ pins: [
119
+ {
120
+ pinId: "R100.1",
121
+ x: 2.9752723250000006,
122
+ y: 0.6000000000000001,
123
+ },
124
+ {
125
+ pinId: "R100.2",
126
+ x: 2.9752723250000006,
127
+ y: -0.4999999999999998,
128
+ },
129
+ ],
130
+ },
131
+ ],
132
+ directConnections: [
133
+ {
134
+ pinIds: ["C101.1", "U100.5"],
135
+ netId: "group > capacitor.C101 > port.pin1 to U100.VOUT",
136
+ },
137
+ {
138
+ pinIds: ["C100.1", "U100.1"],
139
+ netId: "group > capacitor.C100 > port.pin1 to U100.VIN",
140
+ },
141
+ {
142
+ pinIds: ["R100.2", "U100.3"],
143
+ netId: "group > resistor.R100 > port.pin2 to U100.EN",
144
+ },
145
+ ],
146
+ netConnections: [
147
+ {
148
+ netId: "GND",
149
+ pinIds: ["CORNERS.1", "CORNERS.4", "U100.2", "C101.2", "C100.2"],
150
+ netLabelWidth: 0.3,
151
+ },
152
+ {
153
+ netId: "VIN",
154
+ pinIds: ["CORNERS.2", "U100.1", "C100.1", "R100.1"],
155
+ netLabelWidth: 0.3,
156
+ },
157
+ {
158
+ netId: "VOUT",
159
+ pinIds: ["CORNERS.3", "U100.5", "C101.1"],
160
+ netLabelWidth: 0.4,
161
+ },
162
+ {
163
+ netId: "LDO_EN",
164
+ pinIds: ["U100.3", "R100.2"],
165
+ netLabelWidth: 0.6,
166
+ },
167
+ ],
168
+ availableNetLabelOrientations: {
169
+ GND: ["y-"],
170
+ VIN: ["y+"],
171
+ VOUT: ["y+"],
172
+ LDO_EN: ["x-", "x+"],
173
+ },
174
+ maxMspPairDistance: 2.4,
175
+ } as InputProblem
176
+
177
+ export default () => <PipelineDebugger inputProblem={inputProblem} />
@@ -0,0 +1,272 @@
1
+ <svg width="640" height="640" viewBox="0 0 640 640" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="100%" height="100%" fill="white" />
3
+ <g>
4
+ <circle data-type="point" data-label="CORNERS.1
5
+ x-" data-x="-1.4" data-y="-0.6" cx="59.450726978998375" cy="310.27463651050084" r="3" fill="hsl(65, 100%, 50%, 0.8)" />
6
+ </g>
7
+ <g>
8
+ <circle data-type="point" data-label="CORNERS.2
9
+ x-" data-x="-1.4" data-y="0.6" cx="59.450726978998375" cy="232.7302100161551" r="3" fill="hsl(66, 100%, 50%, 0.8)" />
10
+ </g>
11
+ <g>
12
+ <circle data-type="point" data-label="CORNERS.3
13
+ x+" data-x="1.4" data-y="0.6" cx="240.3877221324717" cy="232.7302100161551" r="3" fill="hsl(67, 100%, 50%, 0.8)" />
14
+ </g>
15
+ <g>
16
+ <circle data-type="point" data-label="CORNERS.4
17
+ x+" data-x="1.4" data-y="-0.6" cx="240.3877221324717" cy="310.27463651050084" r="3" fill="hsl(68, 100%, 50%, 0.8)" />
18
+ </g>
19
+ <g>
20
+ <circle data-type="point" data-label="U100.1
21
+ x-" data-x="3.785" data-y="-0.29999999999999993" cx="394.50726978998387" cy="290.8885298869144" r="3" fill="hsl(175, 100%, 50%, 0.8)" />
22
+ </g>
23
+ <g>
24
+ <circle data-type="point" data-label="U100.2
25
+ y-" data-x="4.785" data-y="-1.2999999999999998" cx="459.1276252019386" cy="355.50888529886913" r="3" fill="hsl(176, 100%, 50%, 0.8)" />
26
+ </g>
27
+ <g>
28
+ <circle data-type="point" data-label="U100.3
29
+ x-" data-x="3.785" data-y="-0.4999999999999999" cx="394.50726978998387" cy="303.8126009693053" r="3" fill="hsl(177, 100%, 50%, 0.8)" />
30
+ </g>
31
+ <g>
32
+ <circle data-type="point" data-label="U100.5
33
+ x+" data-x="5.785" data-y="-0.3999999999999999" cx="523.7479806138933" cy="297.35056542810986" r="3" fill="hsl(179, 100%, 50%, 0.8)" />
34
+ </g>
35
+ <g>
36
+ <circle data-type="point" data-label="C101.1
37
+ y+" data-x="6.7" data-y="-0.39999999999999925" cx="582.8756058158319" cy="297.3505654281098" r="3" fill="hsl(218, 100%, 50%, 0.8)" />
38
+ </g>
39
+ <g>
40
+ <circle data-type="point" data-label="C101.2
41
+ y-" data-x="6.7" data-y="-1.4999999999999993" cx="582.8756058158319" cy="368.43295638126006" r="3" fill="hsl(219, 100%, 50%, 0.8)" />
42
+ </g>
43
+ <g>
44
+ <circle data-type="point" data-label="C100.1
45
+ y+" data-x="2.8699999999999997" data-y="-1.2" cx="335.37964458804515" cy="349.04684975767367" r="3" fill="hsl(337, 100%, 50%, 0.8)" />
46
+ </g>
47
+ <g>
48
+ <circle data-type="point" data-label="C100.2
49
+ y-" data-x="2.8699999999999997" data-y="-2.3" cx="335.37964458804515" cy="420.12924071082386" r="3" fill="hsl(338, 100%, 50%, 0.8)" />
50
+ </g>
51
+ <g>
52
+ <circle data-type="point" data-label="R100.1
53
+ y+" data-x="2.9752723250000006" data-y="0.6000000000000003" cx="342.1823796445881" cy="232.73021001615507" r="3" fill="hsl(82, 100%, 50%, 0.8)" />
54
+ </g>
55
+ <g>
56
+ <circle data-type="point" data-label="R100.2
57
+ y-" data-x="2.9752723250000006" data-y="-0.4999999999999998" cx="342.1823796445881" cy="303.8126009693053" r="3" fill="hsl(83, 100%, 50%, 0.8)" />
58
+ </g>
59
+ <g>
60
+ <circle data-type="point" data-label="" data-x="-1.4" data-y="-0.6" cx="59.450726978998375" cy="310.27463651050084" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
61
+ </g>
62
+ <g>
63
+ <circle data-type="point" data-label="" data-x="1.4" data-y="-0.6" cx="240.3877221324717" cy="310.27463651050084" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
64
+ </g>
65
+ <g>
66
+ <circle data-type="point" data-label="" data-x="4.785" data-y="-1.6999999999999993" cx="459.1276252019386" cy="381.357027463651" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
67
+ </g>
68
+ <g>
69
+ <circle data-type="point" data-label="" data-x="2.8699999999999997" data-y="-2.3" cx="335.37964458804515" cy="420.12924071082386" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
70
+ </g>
71
+ <g>
72
+ <circle data-type="point" data-label="" data-x="2.8699999999999997" data-y="-1.2" cx="335.37964458804515" cy="349.04684975767367" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
73
+ </g>
74
+ <g>
75
+ <circle data-type="point" data-label="" data-x="2.9752723250000006" data-y="0.8000000000000005" cx="342.1823796445881" cy="219.80613893376412" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
76
+ </g>
77
+ <g>
78
+ <circle data-type="point" data-label="" data-x="-1.4" data-y="0.6" cx="59.450726978998375" cy="232.7302100161551" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
79
+ </g>
80
+ <g>
81
+ <circle data-type="point" data-label="" data-x="6.2425" data-y="-0.19999999999999923" cx="553.3117932148626" cy="284.4264943457189" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
82
+ </g>
83
+ <g>
84
+ <circle data-type="point" data-label="" data-x="1.4" data-y="0.6" cx="240.3877221324717" cy="232.7302100161551" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
85
+ </g>
86
+ <g>
87
+ <circle data-type="point" data-label="" data-x="2.9752723250000006" data-y="-0.5999999999999999" cx="342.1823796445881" cy="310.2746365105008" r="3" fill="hsl(40, 100%, 50%, 0.9)" />
88
+ </g>
89
+ <g>
90
+ <polyline data-points="6.7,-0.39999999999999925 5.785,-0.3999999999999999" data-type="line" data-label="" points="582.8756058158319,297.3505654281098 523.7479806138933,297.35056542810986" fill="none" stroke="hsl(176, 100%, 50%, 0.8)" stroke-width="1" />
91
+ </g>
92
+ <g>
93
+ <polyline data-points="2.8699999999999997,-1.2 3.785,-0.29999999999999993" data-type="line" data-label="" points="335.37964458804515,349.04684975767367 394.50726978998387,290.8885298869144" fill="none" stroke="hsl(8, 100%, 50%, 0.8)" stroke-width="1" />
94
+ </g>
95
+ <g>
96
+ <polyline data-points="2.9752723250000006,-0.4999999999999998 3.785,-0.4999999999999999" data-type="line" data-label="" points="342.1823796445881,303.8126009693053 394.50726978998387,303.8126009693053" fill="none" stroke="hsl(272, 100%, 50%, 0.8)" stroke-width="1" />
97
+ </g>
98
+ <g>
99
+ <polyline data-points="-1.4,-0.6 1.4,-0.6" data-type="line" data-label="" points="59.450726978998375,310.27463651050084 240.3877221324717,310.27463651050084" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
100
+ </g>
101
+ <g>
102
+ <polyline data-points="-1.4,-0.6 4.785,-1.2999999999999998" data-type="line" data-label="" points="59.450726978998375,310.27463651050084 459.1276252019386,355.50888529886913" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
103
+ </g>
104
+ <g>
105
+ <polyline data-points="-1.4,-0.6 6.7,-1.4999999999999993" data-type="line" data-label="" points="59.450726978998375,310.27463651050084 582.8756058158319,368.43295638126006" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
106
+ </g>
107
+ <g>
108
+ <polyline data-points="-1.4,-0.6 2.8699999999999997,-2.3" data-type="line" data-label="" points="59.450726978998375,310.27463651050084 335.37964458804515,420.12924071082386" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
109
+ </g>
110
+ <g>
111
+ <polyline data-points="1.4,-0.6 4.785,-1.2999999999999998" data-type="line" data-label="" points="240.3877221324717,310.27463651050084 459.1276252019386,355.50888529886913" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
112
+ </g>
113
+ <g>
114
+ <polyline data-points="1.4,-0.6 6.7,-1.4999999999999993" data-type="line" data-label="" points="240.3877221324717,310.27463651050084 582.8756058158319,368.43295638126006" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
115
+ </g>
116
+ <g>
117
+ <polyline data-points="1.4,-0.6 2.8699999999999997,-2.3" data-type="line" data-label="" points="240.3877221324717,310.27463651050084 335.37964458804515,420.12924071082386" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
118
+ </g>
119
+ <g>
120
+ <polyline data-points="4.785,-1.2999999999999998 6.7,-1.4999999999999993" data-type="line" data-label="" points="459.1276252019386,355.50888529886913 582.8756058158319,368.43295638126006" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
121
+ </g>
122
+ <g>
123
+ <polyline data-points="4.785,-1.2999999999999998 2.8699999999999997,-2.3" data-type="line" data-label="" points="459.1276252019386,355.50888529886913 335.37964458804515,420.12924071082386" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
124
+ </g>
125
+ <g>
126
+ <polyline data-points="6.7,-1.4999999999999993 2.8699999999999997,-2.3" data-type="line" data-label="" points="582.8756058158319,368.43295638126006 335.37964458804515,420.12924071082386" fill="none" stroke="hsl(157, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
127
+ </g>
128
+ <g>
129
+ <polyline data-points="-1.4,0.6 3.785,-0.29999999999999993" data-type="line" data-label="" points="59.450726978998375,232.7302100161551 394.50726978998387,290.8885298869144" fill="none" stroke="hsl(27, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
130
+ </g>
131
+ <g>
132
+ <polyline data-points="-1.4,0.6 2.8699999999999997,-1.2" data-type="line" data-label="" points="59.450726978998375,232.7302100161551 335.37964458804515,349.04684975767367" fill="none" stroke="hsl(27, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
133
+ </g>
134
+ <g>
135
+ <polyline data-points="-1.4,0.6 2.9752723250000006,0.6000000000000003" data-type="line" data-label="" points="59.450726978998375,232.7302100161551 342.1823796445881,232.73021001615507" fill="none" stroke="hsl(27, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
136
+ </g>
137
+ <g>
138
+ <polyline data-points="3.785,-0.29999999999999993 2.8699999999999997,-1.2" data-type="line" data-label="" points="394.50726978998387,290.8885298869144 335.37964458804515,349.04684975767367" fill="none" stroke="hsl(27, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
139
+ </g>
140
+ <g>
141
+ <polyline data-points="3.785,-0.29999999999999993 2.9752723250000006,0.6000000000000003" data-type="line" data-label="" points="394.50726978998387,290.8885298869144 342.1823796445881,232.73021001615507" fill="none" stroke="hsl(27, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
142
+ </g>
143
+ <g>
144
+ <polyline data-points="2.8699999999999997,-1.2 2.9752723250000006,0.6000000000000003" data-type="line" data-label="" points="335.37964458804515,349.04684975767367 342.1823796445881,232.73021001615507" fill="none" stroke="hsl(27, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
145
+ </g>
146
+ <g>
147
+ <polyline data-points="1.4,0.6 5.785,-0.3999999999999999" data-type="line" data-label="" points="240.3877221324717,232.7302100161551 523.7479806138933,297.35056542810986" fill="none" stroke="hsl(64, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
148
+ </g>
149
+ <g>
150
+ <polyline data-points="1.4,0.6 6.7,-0.39999999999999925" data-type="line" data-label="" points="240.3877221324717,232.7302100161551 582.8756058158319,297.3505654281098" fill="none" stroke="hsl(64, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
151
+ </g>
152
+ <g>
153
+ <polyline data-points="5.785,-0.3999999999999999 6.7,-0.39999999999999925" data-type="line" data-label="" points="523.7479806138933,297.35056542810986 582.8756058158319,297.3505654281098" fill="none" stroke="hsl(64, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
154
+ </g>
155
+ <g>
156
+ <polyline data-points="3.785,-0.4999999999999999 2.9752723250000006,-0.4999999999999998" data-type="line" data-label="" points="394.50726978998387,303.8126009693053 342.1823796445881,303.8126009693053" fill="none" stroke="hsl(345, 100%, 50%, 0.8)" stroke-width="1" stroke-dasharray="4 2" />
157
+ </g>
158
+ <g>
159
+ <polyline data-points="5.785,-0.3999999999999999 6.2425,-0.3999999999999999 6.2425,-0.19999999999999923 6.7,-0.19999999999999923 6.7,-0.39999999999999925" data-type="line" data-label="" points="523.7479806138933,297.35056542810986 553.3117932148626,297.35056542810986 553.3117932148626,284.4264943457189 582.8756058158319,284.4264943457189 582.8756058158319,297.3505654281098" fill="none" stroke="purple" stroke-width="1" />
160
+ </g>
161
+ <g>
162
+ <polyline data-points="2.9752723250000006,0.6000000000000003 2.9752723250000006,0.8000000000000005 3.3801361625000004,0.8000000000000005 3.3801361625000004,-0.30000000000000004 3.785,-0.30000000000000004" data-type="line" data-label="" points="342.1823796445881,232.73021001615507 342.1823796445881,219.80613893376412 368.344824717286,219.80613893376412 368.344824717286,290.8885298869144 394.50726978998387,290.8885298869144" fill="none" stroke="purple" stroke-width="1" />
163
+ </g>
164
+ <g>
165
+ <polyline data-points="2.9752723250000006,-0.4999999999999998 2.9752723250000006,-0.7 3.585,-0.7 3.585,-0.4999999999999998 3.785,-0.4999999999999998" data-type="line" data-label="" points="342.1823796445881,303.8126009693053 342.1823796445881,316.7366720516963 381.5831987075928,316.7366720516963 381.5831987075928,303.8126009693053 394.50726978998387,303.8126009693053" fill="none" stroke="purple" stroke-width="1" />
166
+ </g>
167
+ <g>
168
+ <polyline data-points="4.785,-1.2999999999999998 4.785,-1.6999999999999993 6.7,-1.6999999999999993 6.7,-1.4999999999999991" data-type="line" data-label="" points="459.1276252019386,355.50888529886913 459.1276252019386,381.357027463651 582.8756058158319,381.357027463651 582.8756058158319,368.43295638126006" fill="none" stroke="purple" stroke-width="1" />
169
+ </g>
170
+ <g>
171
+ <rect data-type="rect" data-label="schematic_component_0" data-x="0" data-y="0" x="59.450726978998375" y="206.8820678513732" width="180.93699515347333" height="129.2407108239095" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015475000000000001" />
172
+ </g>
173
+ <g>
174
+ <rect data-type="rect" data-label="schematic_component_1" data-x="4.785" data-y="-0.3999999999999999" x="394.50726978998387" y="239.1922455573506" width="129.24071082390947" height="116.31663974151854" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015475000000000001" />
175
+ </g>
176
+ <g>
177
+ <rect data-type="rect" data-label="schematic_component_2" data-x="6.7" data-y="-0.9499999999999993" x="565.751211631664" y="297.3505654281098" width="34.24878836833602" height="71.08239095315025" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015475000000000001" />
178
+ </g>
179
+ <g>
180
+ <rect data-type="rect" data-label="schematic_component_3" data-x="2.8699999999999997" data-y="-1.75" x="318.2552504038772" y="349.04684975767367" width="34.24878836833602" height="71.0823909531502" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015475000000000001" />
181
+ </g>
182
+ <g>
183
+ <rect data-type="rect" data-label="schematic_component_4" data-x="2.9752723250000006" data-y="0.050000000000000266" x="331.8607205169629" y="232.73021001615507" width="20.643318255250335" height="71.08239095315025" fill="hsl(24, 100%, 50%, 0.8)" stroke="black" stroke-width="0.015475000000000001" />
184
+ </g>
185
+ <g>
186
+ <rect data-type="rect" data-label="" data-x="-1.5509999999999997" data-y="-0.6" x="40.000000000000014" y="303.8126009693053" width="19.386106623586414" height="12.92407108239098" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
187
+ </g>
188
+ <g>
189
+ <rect data-type="rect" data-label="" data-x="1.5509999999999997" data-y="-0.6" x="240.45234248788364" y="303.8126009693053" width="19.386106623586443" height="12.92407108239098" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
190
+ </g>
191
+ <g>
192
+ <rect data-type="rect" data-label="" data-x="4.785" data-y="-1.8499999999999992" x="452.6655896607431" y="381.357027463651" width="12.924071082390924" height="19.386106623586443" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
193
+ </g>
194
+ <g>
195
+ <rect data-type="rect" data-label="" data-x="2.8699999999999997" data-y="-2.4509999999999996" x="328.9176090468497" y="420.19386106623585" width="12.92407108239098" height="19.386106623586443" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
196
+ </g>
197
+ <g>
198
+ <rect data-type="rect" data-label="" data-x="2.8699999999999997" data-y="-1.0490000000000002" x="328.9176090468497" y="329.5961227786753" width="12.92407108239098" height="19.386106623586443" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
199
+ </g>
200
+ <g>
201
+ <rect data-type="rect" data-label="" data-x="2.9752723250000006" data-y="0.9500000000000005" x="335.72034410339256" y="200.4200323101777" width="12.92407108239098" height="19.386106623586414" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
202
+ </g>
203
+ <g>
204
+ <rect data-type="rect" data-label="" data-x="-1.5509999999999997" data-y="0.6" x="40.000000000000014" y="226.2681744749596" width="19.386106623586414" height="12.92407108239098" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
205
+ </g>
206
+ <g>
207
+ <rect data-type="rect" data-label="" data-x="6.2425" data-y="7.771561172376096e-16" x="546.8497576736672" y="258.578352180937" width="12.92407108239081" height="25.848142164781905" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
208
+ </g>
209
+ <g>
210
+ <rect data-type="rect" data-label="" data-x="1.6009999999999998" data-y="0.6" x="240.45234248788364" y="226.2681744749596" width="25.848142164781905" height="12.92407108239098" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
211
+ </g>
212
+ <g>
213
+ <rect data-type="rect" data-label="" data-x="2.675272325000001" data-y="-0.5999999999999999" x="303.4101663974152" y="303.8126009693053" width="38.772213247172886" height="12.92407108239098" fill="hsl(40, 100%, 50%, 0.35)" stroke="black" stroke-width="0.015475000000000001" />
214
+ </g>
215
+ <g id="crosshair" style="display: none">
216
+ <line id="crosshair-h" y1="0" y2="640" stroke="#666" stroke-width="0.5" />
217
+ <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>
218
+ </g>
219
+ <script>
220
+ <![CDATA[
221
+ document.currentScript.parentElement.addEventListener('mousemove', (e) => {
222
+ const svg = e.currentTarget;
223
+ const rect = svg.getBoundingClientRect();
224
+ const x = e.clientX - rect.left;
225
+ const y = e.clientY - rect.top;
226
+ const crosshair = svg.getElementById('crosshair');
227
+ const h = svg.getElementById('crosshair-h');
228
+ const v = svg.getElementById('crosshair-v');
229
+ const coords = svg.getElementById('coordinates');
230
+
231
+ crosshair.style.display = 'block';
232
+ h.setAttribute('x1', '0');
233
+ h.setAttribute('x2', '640');
234
+ h.setAttribute('y1', y);
235
+ h.setAttribute('y2', y);
236
+ v.setAttribute('x1', x);
237
+ v.setAttribute('x2', x);
238
+ v.setAttribute('y1', '0');
239
+ v.setAttribute('y2', '640');
240
+
241
+ // Calculate real coordinates using inverse transformation
242
+ const matrix = {
243
+ "a": 64.62035541195476,
244
+ "c": 0,
245
+ "e": 149.91922455573504,
246
+ "b": 0,
247
+ "d": -64.62035541195476,
248
+ "f": 271.50242326332796
249
+ };
250
+ // Manually invert and apply the affine transform
251
+ // Since we only use translate and scale, we can directly compute:
252
+ // x' = (x - tx) / sx
253
+ // y' = (y - ty) / sy
254
+ const sx = matrix.a;
255
+ const sy = matrix.d;
256
+ const tx = matrix.e;
257
+ const ty = matrix.f;
258
+ const realPoint = {
259
+ x: (x - tx) / sx,
260
+ y: (y - ty) / sy // Flip y back since we used negative scale
261
+ }
262
+
263
+ coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
264
+ coords.setAttribute('x', (x + 5).toString());
265
+ coords.setAttribute('y', (y - 5).toString());
266
+ });
267
+ document.currentScript.parentElement.addEventListener('mouseleave', () => {
268
+ document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
269
+ });
270
+ ]]>
271
+ </script>
272
+ </svg>
@@ -0,0 +1,183 @@
1
+ import { expect } from "bun:test"
2
+ import { test } from "bun:test"
3
+ import { SchematicTracePipelineSolver, type InputProblem } from "lib/index"
4
+ import "tests/fixtures/matcher"
5
+
6
+ const inputProblem = {
7
+ chips: [
8
+ {
9
+ chipId: "schematic_component_0",
10
+ center: {
11
+ x: 0,
12
+ y: 0,
13
+ },
14
+ width: 2,
15
+ height: 2,
16
+ pins: [
17
+ {
18
+ pinId: "CORNERS.1",
19
+ x: -1.4,
20
+ y: -0.6,
21
+ },
22
+ {
23
+ pinId: "CORNERS.2",
24
+ x: -1.4,
25
+ y: 0.6,
26
+ },
27
+ {
28
+ pinId: "CORNERS.3",
29
+ x: 1.4,
30
+ y: 0.6,
31
+ },
32
+ {
33
+ pinId: "CORNERS.4",
34
+ x: 1.4,
35
+ y: -0.6,
36
+ },
37
+ ],
38
+ },
39
+ {
40
+ chipId: "schematic_component_1",
41
+ center: {
42
+ x: 4.785,
43
+ y: -0.3999999999999999,
44
+ },
45
+ width: 1.2000000000000002,
46
+ height: 1,
47
+ pins: [
48
+ {
49
+ pinId: "U100.1",
50
+ x: 3.785,
51
+ y: -0.29999999999999993,
52
+ },
53
+ {
54
+ pinId: "U100.2",
55
+ x: 4.785,
56
+ y: -1.2999999999999998,
57
+ },
58
+ {
59
+ pinId: "U100.3",
60
+ x: 3.785,
61
+ y: -0.4999999999999999,
62
+ },
63
+ {
64
+ pinId: "U100.5",
65
+ x: 5.785,
66
+ y: -0.3999999999999999,
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ chipId: "schematic_component_2",
72
+ center: {
73
+ x: 6.7,
74
+ y: -0.9499999999999993,
75
+ },
76
+ width: 0.53,
77
+ height: 1.06,
78
+ pins: [
79
+ {
80
+ pinId: "C101.1",
81
+ x: 6.7,
82
+ y: -0.39999999999999925,
83
+ },
84
+ {
85
+ pinId: "C101.2",
86
+ x: 6.7,
87
+ y: -1.4999999999999993,
88
+ },
89
+ ],
90
+ },
91
+ {
92
+ chipId: "schematic_component_3",
93
+ center: {
94
+ x: 2.8699999999999997,
95
+ y: -1.75,
96
+ },
97
+ width: 0.53,
98
+ height: 1.06,
99
+ pins: [
100
+ {
101
+ pinId: "C100.1",
102
+ x: 2.8699999999999997,
103
+ y: -1.2,
104
+ },
105
+ {
106
+ pinId: "C100.2",
107
+ x: 2.8699999999999997,
108
+ y: -2.3,
109
+ },
110
+ ],
111
+ },
112
+ {
113
+ chipId: "schematic_component_4",
114
+ center: {
115
+ x: 2.9752723250000006,
116
+ y: 0.050000000000000266,
117
+ },
118
+ width: 0.3194553499999995,
119
+ height: 1.06,
120
+ pins: [
121
+ {
122
+ pinId: "R100.1",
123
+ x: 2.9752723250000006,
124
+ y: 0.6000000000000001,
125
+ },
126
+ {
127
+ pinId: "R100.2",
128
+ x: 2.9752723250000006,
129
+ y: -0.4999999999999998,
130
+ },
131
+ ],
132
+ },
133
+ ],
134
+ directConnections: [
135
+ {
136
+ pinIds: ["C101.1", "U100.5"],
137
+ netId: "group > capacitor.C101 > port.pin1 to U100.VOUT",
138
+ },
139
+ {
140
+ pinIds: ["C100.1", "U100.1"],
141
+ netId: "group > capacitor.C100 > port.pin1 to U100.VIN",
142
+ },
143
+ {
144
+ pinIds: ["R100.2", "U100.3"],
145
+ netId: "group > resistor.R100 > port.pin2 to U100.EN",
146
+ },
147
+ ],
148
+ netConnections: [
149
+ {
150
+ netId: "GND",
151
+ pinIds: ["CORNERS.1", "CORNERS.4", "U100.2", "C101.2", "C100.2"],
152
+ netLabelWidth: 0.3,
153
+ },
154
+ {
155
+ netId: "VIN",
156
+ pinIds: ["CORNERS.2", "U100.1", "C100.1", "R100.1"],
157
+ netLabelWidth: 0.3,
158
+ },
159
+ {
160
+ netId: "VOUT",
161
+ pinIds: ["CORNERS.3", "U100.5", "C101.1"],
162
+ netLabelWidth: 0.4,
163
+ },
164
+ {
165
+ netId: "LDO_EN",
166
+ pinIds: ["U100.3", "R100.2"],
167
+ netLabelWidth: 0.6,
168
+ },
169
+ ],
170
+ availableNetLabelOrientations: {
171
+ GND: ["y-"],
172
+ VIN: ["y+"],
173
+ VOUT: ["y+"],
174
+ LDO_EN: ["x-", "x+"],
175
+ },
176
+ maxMspPairDistance: 2.4,
177
+ } as InputProblem
178
+
179
+ test("example21", () => {
180
+ const solver = new SchematicTracePipelineSolver(inputProblem)
181
+ solver.solve()
182
+ expect(solver).toMatchSolverSnapshot(import.meta.path)
183
+ })