/** * Blob region geometry. * * A "blob" is the union of one or more axis-aligned grid spans, rendered as * a single closed SVG path with rounded convex AND concave corners. * * Workflow: * buildBlob(spans, cols, rows, layout) * 1. paint spans into a boolean cell grid * 2. validate 4-connectivity (throws on disjoint) * 3. trace boundary edges and chain into CW polygons (pixel coords) * 4. simplify collinear vertices * * blobPathD(blob, radius) * emits an SVG path `d` attribute with rounded corners. */ import type { GridSpan } from '../types.js'; import type { GridLayout } from './grid.js'; export interface BlobBBox { minCol: number; maxCol: number; minRow: number; maxRow: number; } export interface Blob { cols: number; rows: number; /** cellGrid[row][col] = true if covered by at least one span */ cellGrid: boolean[][]; /** Grid-coord bbox of the union */ bbox: BlobBBox; /** Closed polygons in pixel coordinates, traced clockwise */ contours: { x: number; y: number; }[][]; } export declare class DisjointRegionError extends Error { constructor(message?: string); } /** * Build a blob from spans. Throws DisjointRegionError if the union is not * 4-connected (diagonal-only contact counts as disjoint). * * `inset` (px) pulls every boundary vertex inward along the axis-aligned * inward normals of its adjacent edges, creating a visible gap between * neighboring regions. Radius clamping still applies on the offset polygon. */ export declare function buildBlob(spans: GridSpan[], layout: GridLayout, inset?: number): Blob; /** Is the cell at (col, row) part of the blob? */ export declare function isCellFilled(blob: Blob, col: number, row: number): boolean; /** * Emit the `d` attribute for an SVG path that draws the blob with rounded * convex and concave corners. Radius is clamped per-corner to half the * adjacent edge length so arcs never overlap. * * When `inset > 0`, concave corners use radius + 2*inset so that the arc * is concentric with the convex arc of an adjacent region — producing a * uniform 2*inset gap along the entire shared boundary (including corners). */ export declare function blobPathD(blob: Blob, radius: number, inset?: number): string; //# sourceMappingURL=blob.d.ts.map