diff --git a/algos/infinite-grid-ijump-astar/tests/__snapshots__/get-debug-svg.snap.svg b/algos/infinite-grid-ijump-astar/tests/__snapshots__/get-debug-svg.snap.svg new file mode 100644 index 0000000..cd038e9 --- /dev/null +++ b/algos/infinite-grid-ijump-astar/tests/__snapshots__/get-debug-svg.snap.svg @@ -0,0 +1,12 @@ +X0t1_iter[0]X012t1_iter[1] \ No newline at end of file diff --git a/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg b/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg index 07bb5de..c96ff17 100644 --- a/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg +++ b/algos/infinite-grid-ijump-astar/tests/__snapshots__/intersection-with-margin.snap.svg @@ -9,4 +9,4 @@ .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } .pcb-silkscreen-text { fill: #f2eda1; } - X0t1_iter[0] \ No newline at end of file + X0t1_iter[0]X0t1_iter[1]X0t1_iter[2] \ No newline at end of file diff --git a/algos/infinite-grid-ijump-astar/tests/__snapshots__/multilayer-trace.snap.svg b/algos/infinite-grid-ijump-astar/tests/__snapshots__/multilayer-trace.snap.svg index 2b10fb7..73fb9e3 100644 --- a/algos/infinite-grid-ijump-astar/tests/__snapshots__/multilayer-trace.snap.svg +++ b/algos/infinite-grid-ijump-astar/tests/__snapshots__/multilayer-trace.snap.svg @@ -8,4 +8,5 @@ .pcb-silkscreen { fill: none; } .pcb-silkscreen-top { stroke: #f2eda1; } .pcb-silkscreen-bottom { stroke: #f2eda1; } - \ No newline at end of file + .pcb-silkscreen-text { fill: #f2eda1; } + \ No newline at end of file diff --git a/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts b/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts index c8ffff5..5777e33 100644 --- a/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts +++ b/algos/infinite-grid-ijump-astar/tests/fixtures/get-debug-svg.ts @@ -1,4 +1,7 @@ -import { getSimpleRouteJson } from "autorouting-dataset" +import { + getSimpleRouteJson, + type SimplifiedPcbTrace, +} from "autorouting-dataset" import { test, expect } from "bun:test" import { circuitJsonToPcbSvg } from "circuit-to-svg" import { Circuit } from "@tscircuit/core" @@ -7,10 +10,17 @@ import { translate } from "transformation-matrix" import type { AnySoupElement } from "@tscircuit/soup" import type { GeneralizedAstarAutorouter } from "algos/infinite-grid-ijump-astar/v2/lib/GeneralizedAstar" -export const getDebugSvg = ( - inputCircuitJson: AnySoupElement[], - autorouter: GeneralizedAstarAutorouter, -) => { +export const getDebugSvg = ({ + inputCircuitJson, + autorouter, + solution, + rowHeight = 2.5, +}: { + inputCircuitJson: AnySoupElement[] + autorouter: GeneralizedAstarAutorouter + solution?: AnySoupElement[] | SimplifiedPcbTrace[] + rowHeight?: number +}) => { const debugSolutions = Object.entries(autorouter.debugSolutions!).map( ([debugSolutionName, solutionCircuitJson]) => ({ debugSolutionName, @@ -37,10 +47,20 @@ export const getDebugSvg = ( }), ), ), - translate(0, -2 * i), + translate(0, -rowHeight * i), ) aggCircuitJson.push(...translatedCircuitJson) } + const finalCircuitJson = JSON.parse( + JSON.stringify(inputCircuitJson.concat((solution as any) ?? [])), + ) + aggCircuitJson.push( + ...transformPCBElements( + finalCircuitJson, + translate(0, -rowHeight * debugSolutions.length), + ), + ) + return circuitJsonToPcbSvg(aggCircuitJson) } diff --git a/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx b/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx index 60fc676..0257336 100644 --- a/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx +++ b/algos/infinite-grid-ijump-astar/tests/get-debug-svg.test.tsx @@ -30,7 +30,7 @@ test("ijump-astar: intersection with margin", () => { const traces = autorouter.solveAndMapToTraces() - expect(getDebugSvg(inputCircuitJson, autorouter)).toMatchSvgSnapshot( + expect(getDebugSvg({ inputCircuitJson, autorouter })).toMatchSvgSnapshot( import.meta.path, ) }) diff --git a/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx b/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx index 19f3a2f..e1417d5 100644 --- a/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx +++ b/algos/infinite-grid-ijump-astar/tests/intersection-with-margin.test.tsx @@ -44,9 +44,11 @@ test("ijump-astar: intersection with margin", () => { debug: true, }) - const traces = autorouter.solveAndMapToTraces() + const solution = autorouter.solveAndMapToTraces() - expect(getDebugSvg(inputCircuitJson, autorouter)).toMatchSvgSnapshot( - import.meta.path, - ) + expect(solution).toHaveLength(1) + + expect( + getDebugSvg({ inputCircuitJson, autorouter, solution }), + ).toMatchSvgSnapshot(import.meta.path) }) diff --git a/algos/infinite-grid-ijump-astar/v2/lib/IJumpAutorouter.ts b/algos/infinite-grid-ijump-astar/v2/lib/IJumpAutorouter.ts index 6b74976..1bfa6e8 100644 --- a/algos/infinite-grid-ijump-astar/v2/lib/IJumpAutorouter.ts +++ b/algos/infinite-grid-ijump-astar/v2/lib/IJumpAutorouter.ts @@ -53,7 +53,11 @@ export class IJumpAutorouter extends GeneralizedAstarAutorouter { } return true }) - .map((dir) => obstacles.getOrthoDirectionCollisionInfo(node, dir)) + .map((dir) => + obstacles.getOrthoDirectionCollisionInfo(node, dir, { + margin: this.OBSTACLE_MARGIN, + }), + ) // Filter out directions that are too close to the wall .filter((dir) => dir.wallDistance >= this.OBSTACLE_MARGIN) @@ -77,7 +81,7 @@ export class IJumpAutorouter extends GeneralizedAstarAutorouter { wallDir: { ...forwardDir, wallDistance: this.OBSTACLE_MARGIN }, obstacle: node.obstacleHit, obstacles, - OBSTACLE_MARGIN: 0.15, + OBSTACLE_MARGIN: this.OBSTACLE_MARGIN, SHOULD_DETECT_CONJOINED_OBSTACLES: true, }) } diff --git a/algos/infinite-grid-ijump-astar/v2/lib/ObstacleList.ts b/algos/infinite-grid-ijump-astar/v2/lib/ObstacleList.ts index 9ed99b1..0cc0ab8 100644 --- a/algos/infinite-grid-ijump-astar/v2/lib/ObstacleList.ts +++ b/algos/infinite-grid-ijump-astar/v2/lib/ObstacleList.ts @@ -92,6 +92,7 @@ export class ObstacleList { getOrthoDirectionCollisionInfo( point: Point, dir: Direction, + { margin = 0 }: { margin?: number } = {}, ): DirectionWithCollisionInfo { const { x, y } = point const { dx, dy } = dir @@ -99,29 +100,32 @@ export class ObstacleList { let collisionObstacle: ObstacleWithEdges | null = null for (const obstacle of this.obstacles) { - const { left, right, top, bottom } = obstacle + const leftMargin = obstacle.left - margin + const rightMargin = obstacle.right + margin + const topMargin = obstacle.top + margin + const bottomMargin = obstacle.bottom - margin let distance: number | null = null if (dx === 1 && dy === 0) { // Right - if (y >= bottom && y <= top && x < left) { - distance = left - x + if (y > bottomMargin && y < topMargin && x < obstacle.left) { + distance = obstacle.left - x } } else if (dx === -1 && dy === 0) { // Left - if (y >= bottom && y <= top && x > right) { - distance = x - right + if (y > bottomMargin && y < topMargin && x > obstacle.right) { + distance = x - obstacle.right } } else if (dx === 0 && dy === 1) { // Up - if (x >= left && x <= right && y < bottom) { - distance = bottom - y + if (x > leftMargin && x < rightMargin && y < obstacle.bottom) { + distance = obstacle.bottom - y } } else if (dx === 0 && dy === -1) { // Down - if (x >= left && x <= right && y > top) { - distance = y - top + if (x > leftMargin && x < rightMargin && y > obstacle.top) { + distance = y - obstacle.top } }