@tscircuit/copper-pour-solver 0.0.1 → 0.0.3
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/.github/CODEOWNERS +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +95 -14
- package/lib/circuit-json/convert-circuit-json-to-input-problem.ts +2 -0
- package/lib/solvers/CopperPourPipelineSolver.ts +18 -5
- package/lib/solvers/copper-pour/get-board-polygon.ts +20 -5
- package/lib/solvers/copper-pour/process-obstacles.ts +85 -2
- package/lib/types.ts +1 -0
- package/package.json +3 -2
- package/tests/__snapshots__/circuit-7.snap.svg +1 -0
- package/tests/__snapshots__/circuit-8.snap.svg +1 -0
- package/tests/assets/circuit-8.json +846 -0
- package/tests/circuit-7.test.ts +15 -0
- package/tests/circuit-8.test.ts +16 -0
- package/tests/utils/run-solver-and-render-to-svg.ts +1 -0
- package/bun.lock +0 -164
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @seveibar @ShiboSoftwareDev
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface InputPourRegion {
|
|
|
10
10
|
connectivityKey: string;
|
|
11
11
|
padMargin: number;
|
|
12
12
|
traceMargin: number;
|
|
13
|
+
boardEdgeMargin?: number;
|
|
13
14
|
}
|
|
14
15
|
interface BaseInputPad {
|
|
15
16
|
padId: string;
|
|
@@ -52,6 +53,7 @@ declare const convertCircuitJsonToInputProblem: (circuitJson: AnyCircuitElement[
|
|
|
52
53
|
pour_connectivity_key: string;
|
|
53
54
|
pad_margin: number;
|
|
54
55
|
trace_margin: number;
|
|
56
|
+
boardEdgeMargin?: number;
|
|
55
57
|
}) => InputProblem;
|
|
56
58
|
|
|
57
59
|
export { type BaseInputPad, CopperPourPipelineSolver, type InputCircularPad, type InputPad, type InputPourRegion, type InputProblem, type InputRectPad, type InputTracePad, type PipelineOutput, convertCircuitJsonToInputProblem };
|
package/dist/index.js
CHANGED
|
@@ -4,18 +4,29 @@ import { BasePipelineSolver } from "@tscircuit/solver-utils";
|
|
|
4
4
|
// lib/solvers/copper-pour/get-board-polygon.ts
|
|
5
5
|
import Flatten from "@flatten-js/core";
|
|
6
6
|
var getBoardPolygon = (region) => {
|
|
7
|
+
const boardEdgeMargin = region.boardEdgeMargin ?? 0;
|
|
7
8
|
if (region.outline && region.outline.length > 0) {
|
|
8
|
-
|
|
9
|
+
const polygon = new Flatten.Polygon(
|
|
9
10
|
region.outline.map((p) => Flatten.point(p.x, p.y))
|
|
10
11
|
);
|
|
12
|
+
return polygon;
|
|
11
13
|
}
|
|
12
14
|
const { bounds } = region;
|
|
15
|
+
const newBounds = {
|
|
16
|
+
minX: bounds.minX + boardEdgeMargin,
|
|
17
|
+
minY: bounds.minY + boardEdgeMargin,
|
|
18
|
+
maxX: bounds.maxX - boardEdgeMargin,
|
|
19
|
+
maxY: bounds.maxY - boardEdgeMargin
|
|
20
|
+
};
|
|
21
|
+
if (newBounds.minX >= newBounds.maxX || newBounds.minY >= newBounds.maxY) {
|
|
22
|
+
return new Flatten.Polygon();
|
|
23
|
+
}
|
|
13
24
|
return new Flatten.Polygon(
|
|
14
25
|
new Flatten.Box(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
26
|
+
newBounds.minX,
|
|
27
|
+
newBounds.minY,
|
|
28
|
+
newBounds.maxX,
|
|
29
|
+
newBounds.maxY
|
|
19
30
|
).toPoints()
|
|
20
31
|
);
|
|
21
32
|
};
|
|
@@ -46,9 +57,67 @@ var circleToPolygon = (circle, numSegments = 32) => {
|
|
|
46
57
|
var isRectPad = (pad) => pad.shape === "rect";
|
|
47
58
|
var isTracePad = (pad) => pad.shape === "trace";
|
|
48
59
|
var isCircularPad = (pad) => pad.shape === "circle";
|
|
49
|
-
var processObstaclesForPour = (pads, pourConnectivityKey, margins) => {
|
|
60
|
+
var processObstaclesForPour = (pads, pourConnectivityKey, margins, boardOutline) => {
|
|
50
61
|
const polygonsToSubtract = [];
|
|
51
|
-
const { padMargin, traceMargin } = margins;
|
|
62
|
+
const { padMargin, traceMargin, boardEdgeMargin } = margins;
|
|
63
|
+
if (boardOutline && boardOutline.length > 0 && boardEdgeMargin && boardEdgeMargin > 0) {
|
|
64
|
+
const boardPoly = new Flatten3.Polygon(
|
|
65
|
+
boardOutline.map((p) => Flatten3.point(p.x, p.y))
|
|
66
|
+
);
|
|
67
|
+
if (boardPoly.area() < 0) {
|
|
68
|
+
boardPoly.reverse();
|
|
69
|
+
}
|
|
70
|
+
const vertices = boardPoly.vertices;
|
|
71
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
72
|
+
const p1 = vertices[i === 0 ? vertices.length - 1 : i - 1];
|
|
73
|
+
const p2 = vertices[i];
|
|
74
|
+
const p3 = vertices[(i + 1) % vertices.length];
|
|
75
|
+
if (!p1 || !p2 || !p3) continue;
|
|
76
|
+
const v1 = new Flatten3.Vector(p1, p2);
|
|
77
|
+
const v2 = new Flatten3.Vector(p2, p3);
|
|
78
|
+
const crossProduct = v1.cross(v2);
|
|
79
|
+
const circle = new Flatten3.Circle(p2, boardEdgeMargin);
|
|
80
|
+
polygonsToSubtract.push(circleToPolygon(circle));
|
|
81
|
+
if (crossProduct < 0) {
|
|
82
|
+
const box = new Flatten3.Box(
|
|
83
|
+
p2.x - boardEdgeMargin,
|
|
84
|
+
p2.y - boardEdgeMargin,
|
|
85
|
+
p2.x + boardEdgeMargin,
|
|
86
|
+
p2.y + boardEdgeMargin
|
|
87
|
+
);
|
|
88
|
+
polygonsToSubtract.push(new Flatten3.Polygon(box.toPoints()));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
92
|
+
const p1 = vertices[i];
|
|
93
|
+
const p2 = vertices[(i + 1) % vertices.length];
|
|
94
|
+
if (!p1 || !p2) continue;
|
|
95
|
+
const segmentLength = Math.hypot(p1.x - p2.x, p1.y - p2.y);
|
|
96
|
+
if (segmentLength === 0) continue;
|
|
97
|
+
const enlargedWidth = boardEdgeMargin * 2;
|
|
98
|
+
const centerX = (p1.x + p2.x) / 2;
|
|
99
|
+
const centerY = (p1.y + p2.y) / 2;
|
|
100
|
+
const rotationDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
|
|
101
|
+
const w2 = segmentLength / 2;
|
|
102
|
+
const h2 = enlargedWidth / 2;
|
|
103
|
+
const angleRad = rotationDeg * Math.PI / 180;
|
|
104
|
+
const cosAngle = Math.cos(angleRad);
|
|
105
|
+
const sinAngle = Math.sin(angleRad);
|
|
106
|
+
const corners = [
|
|
107
|
+
{ x: -w2, y: -h2 },
|
|
108
|
+
{ x: w2, y: -h2 },
|
|
109
|
+
{ x: w2, y: h2 },
|
|
110
|
+
{ x: -w2, y: h2 }
|
|
111
|
+
];
|
|
112
|
+
const rotatedCorners = corners.map((p) => ({
|
|
113
|
+
x: centerX + p.x * cosAngle - p.y * sinAngle,
|
|
114
|
+
y: centerY + p.x * sinAngle + p.y * cosAngle
|
|
115
|
+
}));
|
|
116
|
+
polygonsToSubtract.push(
|
|
117
|
+
new Flatten3.Polygon(rotatedCorners.map((p) => Flatten3.point(p.x, p.y)))
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
52
121
|
for (const pad of pads) {
|
|
53
122
|
const isOnNet = pad.connectivityKey === pourConnectivityKey;
|
|
54
123
|
if (isOnNet) {
|
|
@@ -184,15 +253,26 @@ var CopperPourPipelineSolver = class extends BasePipelineSolver {
|
|
|
184
253
|
region.connectivityKey,
|
|
185
254
|
{
|
|
186
255
|
padMargin: region.padMargin,
|
|
187
|
-
traceMargin: region.traceMargin
|
|
188
|
-
|
|
256
|
+
traceMargin: region.traceMargin,
|
|
257
|
+
boardEdgeMargin: region.boardEdgeMargin
|
|
258
|
+
},
|
|
259
|
+
region.outline
|
|
189
260
|
);
|
|
190
261
|
let pourPolygons = boardPolygon;
|
|
191
262
|
for (const poly of polygonsToSubtract) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
263
|
+
const currentPolys = Array.isArray(pourPolygons) ? pourPolygons : [pourPolygons];
|
|
264
|
+
const nextPolys = [];
|
|
265
|
+
for (const p of currentPolys) {
|
|
266
|
+
const result = Flatten5.BooleanOperations.subtract(p, poly);
|
|
267
|
+
if (result) {
|
|
268
|
+
if (Array.isArray(result)) {
|
|
269
|
+
nextPolys.push(...result.filter((r) => !r.isEmpty()));
|
|
270
|
+
} else {
|
|
271
|
+
if (!result.isEmpty()) nextPolys.push(result);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
pourPolygons = nextPolys;
|
|
196
276
|
}
|
|
197
277
|
const new_breps = generateBRep(pourPolygons);
|
|
198
278
|
brep_shapes.push(...new_breps);
|
|
@@ -354,7 +434,8 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
|
354
434
|
outline: pcb_board.outline,
|
|
355
435
|
connectivityKey: options.pour_connectivity_key,
|
|
356
436
|
padMargin: options.pad_margin,
|
|
357
|
-
traceMargin: options.trace_margin
|
|
437
|
+
traceMargin: options.trace_margin,
|
|
438
|
+
boardEdgeMargin: options.boardEdgeMargin ?? 0
|
|
358
439
|
}
|
|
359
440
|
];
|
|
360
441
|
return {
|
|
@@ -26,6 +26,7 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
26
26
|
pour_connectivity_key: string
|
|
27
27
|
pad_margin: number
|
|
28
28
|
trace_margin: number
|
|
29
|
+
boardEdgeMargin?: number
|
|
29
30
|
},
|
|
30
31
|
): InputProblem => {
|
|
31
32
|
const source_ports = circuitJson.filter(
|
|
@@ -198,6 +199,7 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
198
199
|
connectivityKey: options.pour_connectivity_key,
|
|
199
200
|
padMargin: options.pad_margin,
|
|
200
201
|
traceMargin: options.trace_margin,
|
|
202
|
+
boardEdgeMargin: options.boardEdgeMargin ?? 0,
|
|
201
203
|
},
|
|
202
204
|
]
|
|
203
205
|
|
|
@@ -28,16 +28,29 @@ export class CopperPourPipelineSolver extends BasePipelineSolver<InputProblem> {
|
|
|
28
28
|
{
|
|
29
29
|
padMargin: region.padMargin,
|
|
30
30
|
traceMargin: region.traceMargin,
|
|
31
|
+
boardEdgeMargin: region.boardEdgeMargin,
|
|
31
32
|
},
|
|
33
|
+
region.outline,
|
|
32
34
|
)
|
|
33
35
|
|
|
34
|
-
let pourPolygons: Flatten.Polygon = boardPolygon
|
|
36
|
+
let pourPolygons: Flatten.Polygon | Flatten.Polygon[] = boardPolygon
|
|
35
37
|
|
|
36
38
|
for (const poly of polygonsToSubtract) {
|
|
37
|
-
|
|
38
|
-
pourPolygons
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const currentPolys = Array.isArray(pourPolygons)
|
|
40
|
+
? pourPolygons
|
|
41
|
+
: [pourPolygons]
|
|
42
|
+
const nextPolys: Flatten.Polygon[] = []
|
|
43
|
+
for (const p of currentPolys) {
|
|
44
|
+
const result = Flatten.BooleanOperations.subtract(p, poly)
|
|
45
|
+
if (result) {
|
|
46
|
+
if (Array.isArray(result)) {
|
|
47
|
+
nextPolys.push(...result.filter((r) => !r.isEmpty()))
|
|
48
|
+
} else {
|
|
49
|
+
if (!result.isEmpty()) nextPolys.push(result)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
pourPolygons = nextPolys
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
const new_breps = generateBRep(pourPolygons)
|
|
@@ -2,18 +2,33 @@ import type { InputPourRegion } from "lib/types"
|
|
|
2
2
|
import Flatten from "@flatten-js/core"
|
|
3
3
|
|
|
4
4
|
export const getBoardPolygon = (region: InputPourRegion): Flatten.Polygon => {
|
|
5
|
+
const boardEdgeMargin = region.boardEdgeMargin ?? 0
|
|
6
|
+
|
|
5
7
|
if (region.outline && region.outline.length > 0) {
|
|
6
|
-
|
|
8
|
+
const polygon = new Flatten.Polygon(
|
|
7
9
|
region.outline.map((p) => Flatten.point(p.x, p.y)),
|
|
8
10
|
)
|
|
11
|
+
return polygon
|
|
9
12
|
}
|
|
13
|
+
|
|
10
14
|
const { bounds } = region
|
|
15
|
+
const newBounds = {
|
|
16
|
+
minX: bounds.minX + boardEdgeMargin,
|
|
17
|
+
minY: bounds.minY + boardEdgeMargin,
|
|
18
|
+
maxX: bounds.maxX - boardEdgeMargin,
|
|
19
|
+
maxY: bounds.maxY - boardEdgeMargin,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (newBounds.minX >= newBounds.maxX || newBounds.minY >= newBounds.maxY) {
|
|
23
|
+
return new Flatten.Polygon()
|
|
24
|
+
}
|
|
25
|
+
|
|
11
26
|
return new Flatten.Polygon(
|
|
12
27
|
new Flatten.Box(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
newBounds.minX,
|
|
29
|
+
newBounds.minY,
|
|
30
|
+
newBounds.maxX,
|
|
31
|
+
newBounds.maxY,
|
|
17
32
|
).toPoints(),
|
|
18
33
|
)
|
|
19
34
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Flatten from "@flatten-js/core"
|
|
2
|
+
import type { Point } from "@tscircuit/math-utils"
|
|
2
3
|
import type {
|
|
3
4
|
InputCircularPad,
|
|
4
5
|
InputPad,
|
|
@@ -20,11 +21,93 @@ const isCircularPad = (pad: InputPad): pad is InputCircularPad =>
|
|
|
20
21
|
export const processObstaclesForPour = (
|
|
21
22
|
pads: InputPad[],
|
|
22
23
|
pourConnectivityKey: string,
|
|
23
|
-
margins: { padMargin: number; traceMargin: number },
|
|
24
|
+
margins: { padMargin: number; traceMargin: number; boardEdgeMargin?: number },
|
|
25
|
+
boardOutline?: Point[],
|
|
24
26
|
): ProcessedObstacles => {
|
|
25
27
|
const polygonsToSubtract: Flatten.Polygon[] = []
|
|
26
28
|
|
|
27
|
-
const { padMargin, traceMargin } = margins
|
|
29
|
+
const { padMargin, traceMargin, boardEdgeMargin } = margins
|
|
30
|
+
|
|
31
|
+
if (
|
|
32
|
+
boardOutline &&
|
|
33
|
+
boardOutline.length > 0 &&
|
|
34
|
+
boardEdgeMargin &&
|
|
35
|
+
boardEdgeMargin > 0
|
|
36
|
+
) {
|
|
37
|
+
const boardPoly = new Flatten.Polygon(
|
|
38
|
+
boardOutline.map((p) => Flatten.point(p.x, p.y)),
|
|
39
|
+
)
|
|
40
|
+
if (boardPoly.area() < 0) {
|
|
41
|
+
boardPoly.reverse()
|
|
42
|
+
}
|
|
43
|
+
const vertices = boardPoly.vertices
|
|
44
|
+
|
|
45
|
+
// Add clearance shapes at vertices
|
|
46
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
47
|
+
const p1 = vertices[i === 0 ? vertices.length - 1 : i - 1]
|
|
48
|
+
const p2 = vertices[i]
|
|
49
|
+
const p3 = vertices[(i + 1) % vertices.length]
|
|
50
|
+
|
|
51
|
+
if (!p1 || !p2 || !p3) continue
|
|
52
|
+
|
|
53
|
+
const v1 = new Flatten.Vector(p1, p2)
|
|
54
|
+
const v2 = new Flatten.Vector(p2, p3)
|
|
55
|
+
const crossProduct = v1.cross(v2)
|
|
56
|
+
|
|
57
|
+
const circle = new Flatten.Circle(p2, boardEdgeMargin)
|
|
58
|
+
polygonsToSubtract.push(circleToPolygon(circle))
|
|
59
|
+
|
|
60
|
+
if (crossProduct < 0) {
|
|
61
|
+
const box = new Flatten.Box(
|
|
62
|
+
p2.x - boardEdgeMargin,
|
|
63
|
+
p2.y - boardEdgeMargin,
|
|
64
|
+
p2.x + boardEdgeMargin,
|
|
65
|
+
p2.y + boardEdgeMargin,
|
|
66
|
+
)
|
|
67
|
+
polygonsToSubtract.push(new Flatten.Polygon(box.toPoints()))
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Add rectangles for each segment to create clearance along edges
|
|
72
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
73
|
+
const p1 = vertices[i]
|
|
74
|
+
const p2 = vertices[(i + 1) % vertices.length]
|
|
75
|
+
|
|
76
|
+
if (!p1 || !p2) continue
|
|
77
|
+
|
|
78
|
+
const segmentLength = Math.hypot(p1.x - p2.x, p1.y - p2.y)
|
|
79
|
+
if (segmentLength === 0) continue
|
|
80
|
+
|
|
81
|
+
const enlargedWidth = boardEdgeMargin * 2
|
|
82
|
+
|
|
83
|
+
const centerX = (p1.x + p2.x) / 2
|
|
84
|
+
const centerY = (p1.y + p2.y) / 2
|
|
85
|
+
const rotationDeg = (Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180) / Math.PI
|
|
86
|
+
|
|
87
|
+
const w2 = segmentLength / 2
|
|
88
|
+
const h2 = enlargedWidth / 2
|
|
89
|
+
|
|
90
|
+
const angleRad = (rotationDeg * Math.PI) / 180
|
|
91
|
+
const cosAngle = Math.cos(angleRad)
|
|
92
|
+
const sinAngle = Math.sin(angleRad)
|
|
93
|
+
|
|
94
|
+
const corners = [
|
|
95
|
+
{ x: -w2, y: -h2 },
|
|
96
|
+
{ x: w2, y: -h2 },
|
|
97
|
+
{ x: w2, y: h2 },
|
|
98
|
+
{ x: -w2, y: h2 },
|
|
99
|
+
]
|
|
100
|
+
|
|
101
|
+
const rotatedCorners = corners.map((p) => ({
|
|
102
|
+
x: centerX + p.x * cosAngle - p.y * sinAngle,
|
|
103
|
+
y: centerY + p.x * sinAngle + p.y * cosAngle,
|
|
104
|
+
}))
|
|
105
|
+
|
|
106
|
+
polygonsToSubtract.push(
|
|
107
|
+
new Flatten.Polygon(rotatedCorners.map((p) => Flatten.point(p.x, p.y))),
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
28
111
|
|
|
29
112
|
for (const pad of pads) {
|
|
30
113
|
const isOnNet = pad.connectivityKey === pourConnectivityKey
|
package/lib/types.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/copper-pour-solver",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"format": "biome format . --write",
|
|
7
|
+
"format:check": "biome format .",
|
|
7
8
|
"build": "tsup-node lib/index.ts --dts --format esm"
|
|
8
9
|
},
|
|
9
10
|
"type": "module",
|
|
10
11
|
"devDependencies": {
|
|
11
12
|
"@biomejs/biome": "^2.2.4",
|
|
12
|
-
"@flatten-js/core": "^1.6.
|
|
13
|
+
"@flatten-js/core": "^1.6.2",
|
|
13
14
|
"@tscircuit/math-utils": "^0.0.25",
|
|
14
15
|
"@tscircuit/solver-utils": "^0.0.3",
|
|
15
16
|
"@types/bun": "latest",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.844"><style></style><rect class="boundary" x="0" y="0" fill="#000" width="800" height="600" data-type="pcb_background" data-pcb-layer="global"/><rect class="pcb-boundary" fill="none" stroke="#fff" stroke-width="0.3" x="127.27272727272725" y="27.272727272727252" width="545.4545454545455" height="545.4545454545455" data-type="pcb_boundary" data-pcb-layer="global"/><path class="pcb-board" d="M 127.27272727272725 572.7272727272727 L 672.7272727272727 572.7272727272727 L 672.7272727272727 27.272727272727252 L 400 27.272727272727252 L 400 300 L 127.27272727272725 300 Z" fill="none" stroke="rgba(255, 255, 255, 0.5)" stroke-width="2.7272727272727275" data-type="pcb_board" data-pcb-layer="board"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="224.77272727272728" y="335.4545454545455" width="27.954545454545453" height="38.18181818181818" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="274.5454545454545" y="335.4545454545455" width="27.954545454545453" height="38.18181818181818" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="497.5" y="335.4545454545455" width="27.954545454545453" height="38.18181818181818" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="547.2727272727273" y="335.4545454545455" width="27.954545454545453" height="38.18181818181818" data-type="pcb_smtpad" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 511.47727272727275 354.54545454545456 L 561.25 354.54545454545456" stroke-width="4.090909090909091" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 561.25 354.54545454545456 L 561.25 354.54545454545456" stroke-width="4.090909090909091" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 511.47727272727275 354.54545454545456 L 288.52272727272725 354.54545454545456" stroke-width="4.090909090909091" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 288.52272727272725 354.54545454545456 L 288.52272727272725 354.54545454545456" stroke-width="4.090909090909091" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-copper-pour pcb-copper-pour-brep" d="M 313.4090909090909 362.0454545454545 L 486.5909090909091 362.04545454545456 L 486.5909090909091 384.54545454545456 L 536.3636363636364 384.54545454545456 L 586.1363636363636 384.54545454545456 L 586.1363636363636 324.54545454545456 L 536.3636363636364 324.54545454545456 L 486.5909090909091 324.54545454545456 L 486.5909090909091 347.04545454545456 L 313.4090909090909 347.04545454545456 L 313.4090909090909 327.27272727272725 L 372.72727272727275 327.27272727272725 L 400 327.27272727272725 L 427.27272727272725 327.27272727272725 L 427.27272727272725 300 L 427.27272727272725 272.72727272727275 L 427.27272727272725 54.54545454545453 L 645.4545454545455 54.54545454545453 L 645.4545454545455 545.4545454545455 L 154.54545454545453 545.4545454545455 L 154.54545454545453 327.27272727272725 L 263.6363636363636 327.27272727272725 L 263.6363636363636 384.54545454545456 L 313.4090909090909 384.54545454545456 L 313.4090909090909 362.0454545454545 Z" fill="rgb(200, 52, 52)" fill-rule="evenodd" fill-opacity="0.5" data-type="pcb_copper_pour" data-pcb-layer="top"/><path class="pcb-silkscreen pcb-silkscreen-top" d="M 288.52272727272725 324.54545454545456 L 219.3181818181818 324.54545454545456 L 219.3181818181818 384.54545454545456 L 288.52272727272725 384.54545454545456" fill="none" stroke="#f2eda1" stroke-width="2.7272727272727275" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_0" data-pcb-silkscreen-path-id="pcb_silkscreen_path_0" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="10.90909090909091" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,263.6363636363636,310.9090909090909)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_0" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">R1</text><path class="pcb-silkscreen pcb-silkscreen-top" d="M 561.25 324.54545454545456 L 492.04545454545456 324.54545454545456 L 492.04545454545456 384.54545454545456 L 561.25 384.54545454545456" fill="none" stroke="#f2eda1" stroke-width="2.7272727272727275" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_1" data-pcb-silkscreen-path-id="pcb_silkscreen_path_1" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="10.90909090909091" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,536.3636363636364,310.9090909090909)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_1" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">R2</text></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.844"><style></style><rect class="boundary" x="0" y="0" fill="#000" width="800" height="600" data-type="pcb_background" data-pcb-layer="global"/><rect class="pcb-boundary" fill="none" stroke="#fff" stroke-width="0.3" x="33.33333333333337" y="22.22222222222223" width="733.3333333333334" height="555.5555555555557" data-type="pcb_boundary" data-pcb-layer="global"/><path class="pcb-board" d="M 144.4444444444445 577.7777777777778 L 700 577.7777777777778 L 744.4444444444445 466.6666666666667 L 766.6666666666667 244.44444444444446 L 744.4444444444445 22.22222222222223 L 700 22.22222222222223 L 588.8888888888889 22.22222222222223 L 588.8888888888889 133.33333333333334 L 477.7777777777778 133.33333333333334 L 477.7777777777778 22.22222222222223 L 144.4444444444445 22.22222222222223 L 33.33333333333337 133.33333333333334 L 144.4444444444445 244.44444444444446 L 255.5555555555556 244.44444444444446 L 255.5555555555556 466.6666666666667 L 144.4444444444445 466.6666666666667 Z" fill="none" stroke="rgba(255, 255, 255, 0.5)" stroke-width="2.2222222222222223" data-type="pcb_board" data-pcb-layer="board"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="335" y="273.33333333333337" width="22.777777777777775" height="31.111111111111107" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="375.55555555555554" y="273.33333333333337" width="22.777777777777775" height="31.111111111111107" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="557.2222222222223" y="273.33333333333337" width="22.777777777777775" height="31.111111111111107" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="597.7777777777778" y="273.33333333333337" width="22.777777777777775" height="31.111111111111107" data-type="pcb_smtpad" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 568.6111111111112 288.8888888888889 L 609.1666666666667 288.8888888888889" stroke-width="3.333333333333333" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 609.1666666666667 288.8888888888889 L 609.1666666666667 288.8888888888889" stroke-width="3.333333333333333" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 568.6111111111112 288.8888888888889 L 386.94444444444446 288.8888888888889" stroke-width="3.333333333333333" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 386.94444444444446 288.8888888888889 L 386.94444444444446 288.8888888888889" stroke-width="3.333333333333333" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-copper-pour pcb-copper-pour-brep" d="M 166.66666666666674 488.8888888888889 L 233.3333333333334 488.8888888888889 L 255.55555555555597 488.8888888888889 L 277.7777777777778 488.8888888888889 L 277.7777777777778 466.6666666666667 L 277.7777777777778 444.44444444444446 L 277.7777777777778 266.6666666666667 L 277.7777777777778 244.44444444444446 L 277.7777777777778 222.22222222222223 L 255.5555555555556 222.22222222222223 L 233.3333333333334 222.22222222222223 L 153.64919027495773 222.22222222222223 L 64.76030138606876 133.33333333333343 L 153.6491902749578 44.44444444444443 L 455.5555555555556 44.444444444444514 L 455.5555555555556 111.11111111111114 L 455.5555555555556 133.33333333333337 L 455.5555555555556 155.55555555555557 L 477.7777777777778 155.55555555555557 L 500.00000000000006 155.55555555555557 L 566.6666666666667 155.55555555555557 L 588.8888888888889 155.55555555555557 L 611.1111111111111 155.55555555555557 L 611.1111111111111 133.33333333333334 L 611.1111111111111 111.11111111111114 L 611.1111111111111 44.44444444444446 L 700 44.44444444444446 L 724.3336097308425 44.44444444444446 L 744.3336097308425 244.44444444444466 L 722.6450571331745 461.32997042112515 L 684.9548230794022 555.5555555555555 L 166.66666666666674 555.5555555555555 L 166.66666666666674 488.8888888888889 Z M 407.2222222222223 295 L 548.3333333333334 295 L 548.3333333333334 313.33333333333337 L 588.8888888888889 313.33333333333337 L 629.4444444444445 313.33333333333337 L 629.4444444444445 264.44444444444446 L 588.8888888888889 264.44444444444446 L 548.3333333333334 264.44444444444446 L 548.3333333333334 282.7777777777778 L 407.2222222222223 282.77777777777777 L 407.2222222222223 264.44444444444446 L 366.6666666666667 264.44444444444446 L 366.6666666666667 313.33333333333337 L 407.2222222222223 313.33333333333337 L 407.2222222222223 295 Z" fill="rgb(200, 52, 52)" fill-rule="evenodd" fill-opacity="0.5" data-type="pcb_copper_pour" data-pcb-layer="top"/><path class="pcb-silkscreen pcb-silkscreen-top" d="M 386.94444444444446 264.44444444444446 L 330.5555555555556 264.44444444444446 L 330.5555555555556 313.33333333333337 L 386.94444444444446 313.33333333333337" fill="none" stroke="#f2eda1" stroke-width="2.2222222222222223" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_0" data-pcb-silkscreen-path-id="pcb_silkscreen_path_0" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="8.88888888888889" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,366.66666666666674,253.33333333333334)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_0" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">R1</text><path class="pcb-silkscreen pcb-silkscreen-top" d="M 609.1666666666667 264.44444444444446 L 552.7777777777778 264.44444444444446 L 552.7777777777778 313.33333333333337 L 609.1666666666667 313.33333333333337" fill="none" stroke="#f2eda1" stroke-width="2.2222222222222223" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_1" data-pcb-silkscreen-path-id="pcb_silkscreen_path_1" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="8.88888888888889" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,588.8888888888889,253.33333333333334)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_1" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">R2</text></svg>
|