/**
 * Terrain layout resolver — turns a {@link TerrainLayout} (template references +
 * centroid-anchored placements + rotation/mirror) into absolute board-space
 * polygon vertices. This is the shared geometry contract pinned by the
 * `conformance/terrain-resolver` corpus; the Rust crate implements the same
 * function and must reproduce these vertices byte-for-byte (4-dp rounded).
 *
 * ## Transform contract
 *
 * Frames are board inches, origin at a board corner, **y-down** (per
 * `common.schema.json#/$defs/vec2`). A footprint is authored in natural local
 * y-down coordinates; the resolver derives its **polygon area centroid** and
 * treats local vertices as `(v - centroid)`, so `position` always denotes the
 * centroid and is invariant under rotation and mirror.
 *
 * Local → board, for an unparented piece, is `mirror → rotate → translate`:
 *
 *   board = position + R_cw(rotation) · M(mirror) · (v - centroid)
 *
 * with `M`: horizontal → (-x, y), vertical → (x, -y); and `R_cw(θ)` a clockwise
 * rotation in the y-down frame, `[[cosθ, -sinθ], [sinθ, cosθ]]`.
 *
 * A feature with a `parent_area_id` (or a template's composed feature) is first
 * placed in the parent area's **centroid-local frame** (origin at the area
 * centroid), then carried through the area's own placement:
 *
 *   board = T_area ∘ R_area ∘ M_area ( featurePos + R_feat · M_feat · (w - C_feat) )
 *
 * ## Emission order (a pinned invariant)
 *
 * Pieces are emitted in `layout.pieces` order. When a piece instances an area
 * template that carries composed `features`, those features are emitted
 * immediately after their area, in template-declaration order.
 */
export interface Vec2 {
    x: number;
    y: number;
}
export type Footprint = {
    type: "rectangle";
    width: number;
    height: number;
} | {
    type: "right-triangle";
    width: number;
    height: number;
} | {
    type: "polygon";
    points: Vec2[];
};
export type Mirror = "none" | "horizontal" | "vertical";
/** A board edge a card dimension is measured from. left/right pin x; top/bottom pin y. */
export type BoardEdge = "left" | "right" | "top" | "bottom";
/**
 * Which feature of the placed area a dimension line reaches: a specific
 * footprint vertex (by index, in {@link footprintVertices} order), or one of
 * the placed area's axis-aligned bounding faces ("the left face", etc.).
 */
export type FeatureRef = {
    kind: "vertex";
    index: number;
} | {
    kind: "face";
    side: "min-x" | "max-x" | "min-y" | "max-y";
};
/**
 * One authored measurement keystone: the dimension line a reference card
 * prints so a player can place the piece with a tape measure. Only the
 * selection is stored — the distance is always derived from resolved geometry
 * (see `keystoneMeasurements`), so a keystone can never disagree with the
 * layout.
 */
export interface Keystone {
    edge: BoardEdge;
    ref: FeatureRef;
}
export interface ComposedFeature {
    id?: string;
    template: string;
    position: Vec2;
    rotation_degrees?: number;
    mirror?: Mirror;
    floor?: number;
}
export interface TerrainTemplate {
    id: string;
    name?: string;
    kind: "area" | "feature";
    footprint: Footprint;
    default_height_inches?: number;
    default_blocking?: boolean;
    default_terrain_area_keywords?: string[];
    features?: ComposedFeature[];
}
export interface LayoutPiece {
    id?: string;
    name?: string;
    piece_type?: "area" | "feature";
    template?: string;
    footprint?: Footprint;
    position: Vec2;
    rotation_degrees?: number;
    mirror?: Mirror;
    parent_area_id?: string;
    floor?: number;
    height_inches?: number;
    terrain_area_keywords?: string[];
    link_group?: string;
    keystones?: Keystone[];
}
export interface TerrainLayout {
    id: string;
    name: string;
    pieces?: LayoutPiece[];
}
export interface ResolvedPiece {
    /** Layout-local id when present, else the piece name, else null. */
    id: string | null;
    name: string | null;
    piece_type: "area" | "feature";
    floor: number;
    /** Absolute board-space polygon vertices, y-down. */
    vertices: Vec2[];
}
/** A footprint's polygon vertices in natural local (y-down) coordinates. */
export declare function footprintVertices(fp: Footprint): Vec2[];
/**
 * Polygon area centroid (shoelace). Falls back to the vertex mean when the
 * polygon is degenerate (zero signed area, e.g. collinear points) so the
 * resolver never divides by zero.
 */
export declare function polygonCentroid(verts: Vec2[]): Vec2;
/**
 * The board-space offset of each footprint vertex from the piece centroid,
 * after mirror + rotation but before translation. Adding `position` to each
 * gives the resolved board vertices; this is the orientation-only part a
 * card-measurement solver inverts to recover the centroid. Vertex order matches
 * {@link footprintVertices}.
 */
export declare function orientedOffsets(footprint: Footprint, rotation: number, mirror: Mirror): Vec2[];
export declare class TerrainResolveError extends Error {
}
/**
 * Resolve a layout to absolute board-space vertices per piece. `templates` is
 * the catalog a piece's `template` references resolve against.
 */
export declare function resolveLayout(layout: TerrainLayout, templates: TerrainTemplate[]): ResolvedPiece[];
//# sourceMappingURL=resolve.d.ts.map