From 77a72580f9570e32b0558da7bf0458ccb04fc7ea Mon Sep 17 00:00:00 2001 From: adminlmz Date: Mon, 11 May 2026 11:45:42 +0000 Subject: [PATCH] feat: specialized horizontal row layout for decoupling capacitor partitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When SingleInnerPartitionPackingSolver encounters a partition with partitionType === "decoupling_caps", bypass PackSolver2 and arrange caps in a clean horizontal row instead. Changes: - Added createDecouplingCapLayout() method - Caps are placed in a single row with consistent 0° rotation - Even spacing using decouplingCapsGap (default 0.5) - Centered around origin for clean alignment - General partitions still use PackSolver2 as before Closes #15 --- .../SingleInnerPartitionPackingSolver.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts b/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts index 88db103..dc8768e 100644 --- a/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts +++ b/lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts @@ -1,6 +1,9 @@ /** * Packs components within a single partition to create an optimal internal layout. * Uses a packing algorithm to arrange chips and their connections within the partition. + * + * For decoupling capacitor partitions, uses a specialized horizontal row layout + * instead of the general-purpose PackSolver2. */ import type { GraphicsObject } from "graphics-debug" @@ -38,6 +41,14 @@ export class SingleInnerPartitionPackingSolver extends BaseSolver { } override _step() { + // Specialized layout for decoupling capacitor partitions: + // Arrange caps in a clean horizontal row instead of using PackSolver2 + if (this.partitionInputProblem.partitionType === "decoupling_caps") { + this.layout = this.createDecouplingCapLayout() + this.solved = true + return + } + // Initialize PackSolver2 if not already created if (!this.activeSubSolver) { const packInput = this.createPackInput() @@ -64,6 +75,47 @@ export class SingleInnerPartitionPackingSolver extends BaseSolver { } } + /** + * Creates a clean horizontal row layout for decoupling capacitors. + * Caps are placed in a single row with consistent orientation and even spacing. + */ + private createDecouplingCapLayout(): OutputLayout { + const chipEntries = Object.entries(this.partitionInputProblem.chipMap) + const gap = this.partitionInputProblem.decouplingCapsGap ?? 0.5 + + // Calculate total width needed + let totalWidth = 0 + const chipWidths: Array<{ chipId: string; width: number; height: number }> = [] + + for (const [chipId, chip] of chipEntries) { + const width = chip.size.x + const height = chip.size.y + chipWidths.push({ chipId, width, height }) + totalWidth += width + } + + // Add gaps between caps + totalWidth += gap * (chipEntries.length - 1) + + // Place caps centered around origin in a horizontal row + const chipPlacements: Record = {} + let currentX = -totalWidth / 2 + + for (const { chipId, width } of chipWidths) { + chipPlacements[chipId] = { + x: currentX + width / 2, + y: 0, + ccwRotationDegrees: 0, + } + currentX += width + gap + } + + return { + chipPlacements, + groupPlacements: {}, + } + } + private createPackInput(): PackInput { // Fall back to filtered mapping (weak + strong) const pinToNetworkMap = createFilteredNetworkMapping({