/**
 * Card-measurement centroid solver — the inverse of the resolver's placement.
 *
 * Reference cards locate a terrain area by dimension lines: "this feature of the
 * area is D inches from a board edge". The feature referenced varies per card
 * and per piece, which is exactly why a single canonical anchor (the centroid)
 * is hard to read off a card directly. This solver lets a user transcribe the
 * card verbatim — pick the template, set the orientation shown, then enter one
 * horizontal and one vertical dimension line against whatever feature the card
 * happens to draw — and back-solves the centroid `position` the schema stores.
 *
 * Because the centroid is rotation- and mirror-invariant, orientation is fixed
 * first; each dimension line then pins one axis of the centroid in closed form.
 */
import { type BoardEdge, type FeatureRef, type Footprint, type Mirror, type Vec2 } from "./resolve.js";
export type { BoardEdge, FeatureRef } from "./resolve.js";
/** One card dimension line: `distance` inches from `edge` to `feature`. */
export interface DimensionLine {
    edge: BoardEdge;
    distance: number;
    feature: FeatureRef;
}
export interface SolveInput {
    footprint: Footprint;
    rotation: number;
    mirror: Mirror;
    /** Board extents in inches (40kdc standard is 60 × 44). */
    board: {
        width: number;
        height: number;
    };
    /** Two perpendicular dimension lines: exactly one must pin x, one must pin y. */
    lines: [DimensionLine, DimensionLine];
}
export declare class TerrainSolveError extends Error {
}
/**
 * Back-solve the centroid `position` from a template, its orientation, and two
 * perpendicular card dimension lines. Closed form — one x-line and one y-line
 * pin the two unknowns directly.
 */
export declare function solveCentroid(input: SolveInput): Vec2;
/**
 * One triangulation measurement: `distance` inches from board `edge` to a
 * specific footprint vertex (corner). Faces are intentionally excluded — an
 * arbitrarily-rotated piece has no axis-aligned face to measure to.
 */
export interface TriangulationLine {
    edge: BoardEdge;
    distance: number;
    vertex: number;
}
export interface TriangulateInput {
    footprint: Footprint;
    mirror: Mirror;
    board: {
        width: number;
        height: number;
    };
    /**
     * Three corner measurements. At least two must share an axis (left/right or
     * top/bottom) to fix the angle, and at least one must pin the other axis.
     */
    lines: [TriangulationLine, TriangulationLine, TriangulationLine];
    /** Current rotation in degrees, used to choose between the two angle roots. */
    rotationHint?: number;
}
/**
 * Back-solve a piece's centroid AND rotation from three card measurements to
 * specific footprint corners — the inverse needed for pieces at non-90° angles,
 * where the card pins three corner-to-edge distances rather than one per axis.
 *
 * Closed form: with the (unknown) rotation θ, each corner `v` resolves to
 * `centroid + R(θ)·v`. Subtracting two same-axis measurements cancels the
 * centroid and leaves `A·cosθ + B·sinθ = C`, solved as `θ = atan2(B,A) ±
 * acos(C/√(A²+B²))`; the root nearest `rotationHint` is chosen. One measurement
 * on each axis then pins the centroid.
 */
export declare function solveCentroidTriangulated(input: TriangulateInput): {
    x: number;
    y: number;
    rotation: number;
};
//# sourceMappingURL=solve.d.ts.map