2.2 KiB
optimizer/merge/merge.ts — adjacent-rect merge pass
(no submodules)
Purpose
This module owns mergeAdjacentRects, the post-processing pass that
combines pairs of edge-sharing same-extent rectangles into a single larger
rectangle, provided the merged span lies entirely inside the available
mask. It is the cheapest of the optimiser passes and runs after every
covering strategy in the layer pipeline.
Features
- Merges along both axes: two rects with the same
yandhmerge horizontally when adjacent; two rects with the samexandwmerge vertically when adjacent. - Iterates until a full pass produces no merges, so chains of three or
more rects collapse to one in
O(n²)per pass andO(k · n²)overall forkpasses (bounded by the rect count). - Available-mask check (
isFullyAvailable) guarantees the merged span never paints transparent cells.
Usage: Basic
import { mergeAdjacentRects } from "@suaveplan/emblem-solver";
const merged = mergeAdjacentRects(
[
{ x: 0, y: 0, w: 1, h: 1 },
{ x: 1, y: 0, w: 1, h: 1 },
],
fullyAvailableGrid
);
// merged === [{ x: 0, y: 0, w: 2, h: 1 }]
Usage: Advanced
import { mergeAdjacentRects } from "@suaveplan/emblem-solver";
let rects = greedyCover;
rects = mergeAdjacentRects(rects, available);
rects = mergeAdjacentRects(rects, available); // idempotent — no further change
API Reference
| Symbol | Kind | Description |
|---|---|---|
mergeAdjacentRects(rects, available) |
fn | Greedily merge edge-sharing same-extent rects |
Implementation Notes
The inner tryMerge first tests the horizontal merge (same y, same
h, sharing an edge in x), then the vertical merge (same x, same
w, sharing an edge in y). Either form checks the combined rectangle
against available before accepting; this avoids painting through
transparent pixels. The outer loop terminates when a full pass produces
zero merges, so each call is idempotent. We deliberately do not try
non-same-extent merges here — that is the job of optimiseOverlap,
which can produce overlapping output and is therefore a strictly stronger
(but more expensive) operation.