Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,31 @@ export class SchematicTraceSingleLineSolver extends BaseSolver {
// If this segment would cross any restricted center line, reject the candidate path.
const EPS = 1e-9
for (const [, rcl] of restrictedCenterLines) {
const bounds = rcl.bounds
if (rcl.axes.has("x") && typeof rcl.x === "number") {
// segment strictly crosses vertical center line
// segment strictly crosses vertical center line near the chip bounds
if ((start.x - rcl.x) * (end.x - rcl.x) < -EPS) {
pathIsValid = false
break
const segMinY = Math.min(start.y, end.y)
const segMaxY = Math.max(start.y, end.y)
const overlapY =
Math.min(segMaxY, bounds.maxY) - Math.max(segMinY, bounds.minY)
if (overlapY > EPS) {
pathIsValid = false
break
}
}
}
if (rcl.axes.has("y") && typeof rcl.y === "number") {
// segment strictly crosses horizontal center line
// segment strictly crosses horizontal center line near the chip bounds
if ((start.y - rcl.y) * (end.y - rcl.y) < -EPS) {
pathIsValid = false
break
const segMinX = Math.min(start.x, end.x)
const segMaxX = Math.max(start.x, end.x)
const overlapX =
Math.min(segMaxX, bounds.maxX) - Math.max(segMinX, bounds.minX)
if (overlapX > EPS) {
pathIsValid = false
break
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
InputProblem,
PinId,
} from "lib/types/InputProblem"
import { getInputChipBounds } from "lib/solvers/GuidelinesSolver/getInputChipBounds"
import { getPinDirection } from "./getPinDirection"

type ChipPin = InputPin & { chipId: ChipId }
Expand All @@ -19,6 +20,7 @@ export type RestrictedCenterLine = {
x?: number
y?: number
axes: Set<"x" | "y">
bounds: ReturnType<typeof getInputChipBounds>
}

export const getRestrictedCenterLines = (params: {
Expand Down Expand Up @@ -107,7 +109,10 @@ export const getRestrictedCenterLines = (params: {
// are present among related pins on the chip.
for (const [chipId, faces] of chipFacingMap) {
const axes = new Set<"x" | "y">()
const rcl: RestrictedCenterLine = { axes }
const chip = chipMap[chipId]
if (!chip) continue
const bounds = getInputChipBounds(chip)
const rcl: RestrictedCenterLine = { axes, bounds }

// determine whether any side on this chip has more than one pin
const counts = faces.counts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { expect, test } from "bun:test"
import { calculateElbow } from "calculate-elbow"
import { SchematicTraceSingleLineSolver } from "lib/solvers/SchematicTraceLinesSolver/SchematicTraceSingleLineSolver/SchematicTraceSingleLineSolver"
import type { InputChip, InputProblem } from "lib/types/InputProblem"

const buildChip = (
chipId: string,
center: { x: number; y: number },
width: number,
height: number,
pins: Array<{ pinId: string; x: number; y: number }>,
): InputChip => ({
chipId,
center,
width,
height,
pins,
})

test("allows long traces when restricted center line is far away", () => {
const chipA = buildChip("A", { x: 0, y: 0 }, 0.4, 0.4, [
{ pinId: "A1", x: 0, y: 0 },
])
const chipB = buildChip("B", { x: 10, y: 0 }, 0.4, 0.4, [
{ pinId: "B1", x: 10, y: 0 },
])
const chipC = buildChip("C", { x: 5, y: 10 }, 1, 1, [
{ pinId: "C1", x: 4.5, y: 10 },
{ pinId: "C2", x: 5.5, y: 10 },
])

const inputProblem: InputProblem = {
chips: [chipA, chipB, chipC],
directConnections: [
{ pinIds: ["A1", "C1"], netId: "N1" },
{ pinIds: ["B1", "C2"], netId: "N1" },
],
netConnections: [],
availableNetLabelOrientations: {},
}

const pins = [
{ pinId: "A1", x: 0, y: 0, chipId: "A", _facingDirection: "x+" as const },
{ pinId: "B1", x: 10, y: 0, chipId: "B", _facingDirection: "x-" as const },
]

const solver = new SchematicTraceSingleLineSolver({
pins: pins as any,
guidelines: [],
inputProblem,
chipMap: { A: chipA, B: chipB, C: chipC },
})

solver.solve()

expect(solver.solved).toBe(true)
expect(solver.failed).toBe(false)

const baseElbow = calculateElbow(
{ x: pins[0].x, y: pins[0].y, facingDirection: pins[0]._facingDirection },
{ x: pins[1].x, y: pins[1].y, facingDirection: pins[1]._facingDirection },
{ overshoot: 0.2 },
)

expect(solver.solvedTracePath).toEqual(baseElbow)
})