From f33932ac45f5771a29b14ac5e3facb6d34e61c33 Mon Sep 17 00:00:00 2001 From: seveibar Date: Wed, 23 Oct 2024 22:34:59 -0700 Subject: [PATCH] add get schematic bounds method --- .../get-schematic-bounds-from-circuit-json.ts | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 lib/sch/get-schematic-bounds-from-circuit-json.ts diff --git a/lib/sch/get-schematic-bounds-from-circuit-json.ts b/lib/sch/get-schematic-bounds-from-circuit-json.ts new file mode 100644 index 0000000..2a59b80 --- /dev/null +++ b/lib/sch/get-schematic-bounds-from-circuit-json.ts @@ -0,0 +1,64 @@ +import type { AnyCircuitElement } from "circuit-json" + +interface Bounds { + minX: number + minY: number + maxX: number + maxY: number +} + +export function getSchematicBoundsFromCircuitJson( + soup: AnyCircuitElement[], + padding = 0.5, +): Bounds { + let minX = Number.POSITIVE_INFINITY + let minY = Number.POSITIVE_INFINITY + let maxX = Number.NEGATIVE_INFINITY + let maxY = Number.NEGATIVE_INFINITY + + const portSize = 0.2 + + // Find the bounds + for (const item of soup) { + if (item.type === "schematic_component") { + updateBounds(item.center, item.size, item.rotation || 0) + } else if (item.type === "schematic_port") { + updateBounds(item.center, { width: portSize, height: portSize }, 0) + } else if (item.type === "schematic_debug_object") { + if (item.shape === "rect") { + updateBounds(item.center, item.size, 0) + } else if (item.shape === "line") { + updateBounds(item.start, { width: 0.1, height: 0.1 }, 0) + updateBounds(item.end, { width: 0.1, height: 0.1 }, 0) + } + } + } + + // Add padding to bounds + minX -= padding + minY -= padding + maxX += padding + maxY += padding + + return { minX, minY, maxX, maxY } + + function updateBounds(center: any, size: any, rotation: number) { + const corners = [ + { x: -size.width / 2, y: -size.height / 2 }, + { x: size.width / 2, y: -size.height / 2 }, + { x: size.width / 2, y: size.height / 2 }, + { x: -size.width / 2, y: size.height / 2 }, + ] + + for (const corner of corners) { + const rotatedX = + corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x + const rotatedY = + corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y + minX = Math.min(minX, rotatedX) + minY = Math.min(minY, rotatedY) + maxX = Math.max(maxX, rotatedX) + maxY = Math.max(maxY, rotatedY) + } + } +}