import LineSegment2 from './LineSegment2';
import Mat33 from '../Mat33';
import Rect2 from './Rect2';
import { Point2 } from '../Vec2';
import Parameterized2DShape from './Parameterized2DShape';
/** Identifiers for different path commands. These commands can make up a {@link Path}. */
export declare enum PathCommandType {
    LineTo = 0,
    MoveTo = 1,
    CubicBezierTo = 2,
    QuadraticBezierTo = 3
}
export interface CubicBezierPathCommand {
    kind: PathCommandType.CubicBezierTo;
    controlPoint1: Point2;
    controlPoint2: Point2;
    endPoint: Point2;
}
export interface QuadraticBezierPathCommand {
    kind: PathCommandType.QuadraticBezierTo;
    controlPoint: Point2;
    endPoint: Point2;
}
export interface LinePathCommand {
    kind: PathCommandType.LineTo;
    point: Point2;
}
export interface MoveToPathCommand {
    kind: PathCommandType.MoveTo;
    point: Point2;
}
export type PathCommand = CubicBezierPathCommand | QuadraticBezierPathCommand | MoveToPathCommand | LinePathCommand;
export interface IntersectionResult {
    curve: Parameterized2DShape;
    curveIndex: number;
    /** Parameter value for the closest point **on** the path to the intersection. @internal */
    parameterValue: number;
    /** Point at which the intersection occured. */
    point: Point2;
}
/** Options for {@link Path.splitNear} and {@link Path.splitAt} */
export interface PathSplitOptions {
    /**
     * Allows mapping points on newly added segments. This is useful, for example,
     * to round points to prevent long decimals when later saving.
     */
    mapNewPoint?: (point: Point2) => Point2;
}
/**
 * Allows indexing a particular part of a path.
 *
 * @see {@link Path.at} {@link Path.tangentAt}
 */
export interface CurveIndexRecord {
    curveIndex: number;
    parameterValue: number;
}
/** Returns a positive number if `a` comes after `b`, 0 if equal, and negative otherwise. */
export declare const compareCurveIndices: (a: CurveIndexRecord, b: CurveIndexRecord) => number;
/**
 * Returns a version of `index` with its parameter value incremented by `stepBy`
 * (which can be either positive or negative).
 */
export declare const stepCurveIndexBy: (index: CurveIndexRecord, stepBy: number) => CurveIndexRecord;
/**
 * Represents a union of lines and curves.
 *
 * To create a path from a string, see {@link fromString}.
 *
 * @example
 * ```ts,runnable,console
 * import {Path, Mat33, Vec2, LineSegment2} from '@js-draw/math';
 *
 * // Creates a path from an SVG path string.
 * // In this case,
 * // 1. Move to (0,0)
 * // 2. Line to (100,0)
 * const path = Path.fromString('M0,0 L100,0');
 *
 * // Logs the distance from (10,0) to the curve 1 unit
 * // away from path. This curve forms a stroke with the path at
 * // its center.
 * const strokeRadius = 1;
 * console.log(path.signedDistance(Vec2.of(10,0), strokeRadius));
 *
 * // Log a version of the path that's scaled by a factor of 4.
 * console.log(path.transformedBy(Mat33.scaling2D(4)).toString());
 *
 * // Log all intersections of a stroked version of the path with
 * // a vertical line segment.
 * // (Try removing the `strokeRadius` parameter).
 * const segment = new LineSegment2(Vec2.of(5, -100), Vec2.of(5, 100));
 * console.log(path.intersection(segment, strokeRadius).map(i => i.point));
 * ```
 */
export declare class Path {
    readonly startPoint: Point2;
    /**
     * A rough estimate of the bounding box of the path.
     * A slight overestimate.
     * See {@link getExactBBox}
     */
    readonly bbox: Rect2;
    /** The individual shapes that make up this path. */
    readonly parts: Readonly<PathCommand>[];
    /**
     * Creates a new `Path` that starts at `startPoint` and is made up of the path commands,
     * `parts`.
     *
     * See also {@link fromString}
     */
    constructor(startPoint: Point2, parts: Readonly<PathCommand>[]);
    /**
     * Computes and returns the full bounding box for this path.
     *
     * If a slight over-estimate of a path's bounding box is sufficient, use
     * {@link bbox} instead.
     */
    getExactBBox(): Rect2;
    private cachedGeometry;
    get geometry(): Parameterized2DShape[];
    /**
     * Iterates through the start/end points of each component in this path.
     *
     * If a start point is equivalent to the end point of the previous segment,
     * the point is **not** emitted twice.
     */
    startEndPoints(): Generator<import("../Vec3").Vec3, undefined, unknown>;
    private cachedPolylineApproximation;
    polylineApproximation(): LineSegment2[];
    static computeBBoxForSegment(startPoint: Point2, part: PathCommand): Rect2;
    /**
     * Returns the signed distance between `point` and a curve `strokeRadius` units
     * away from this path.
     *
     * This returns the **signed distance**, which means that points inside this shape
     * have their distance negated. For example,
     * ```ts,runnable,console
     * import {Path, Vec2} from '@js-draw/math';
     * console.log(Path.fromString('m0,0 L100,0').signedDistance(Vec2.zero, 1));
     * ```
     * would print `-1` because (0,0) is on `m0,0 L100,0` and thus one unit away from its boundary.
     *
     * **Note**: `strokeRadius = strokeWidth / 2`
     */
    signedDistance(point: Point2, strokeRadius: number): number;
    /**
     * Let `S` be a closed path a distance `strokeRadius` from this path.
     *
     * @returns Approximate intersections of `line` with `S` using ray marching, starting from
     * 	        both end points of `line` and each point in `additionalRaymarchStartPoints`.
     */
    private raymarchIntersectionWith;
    /**
     * Returns a list of intersections with this path. If `strokeRadius` is given,
     * intersections are approximated with the surface `strokeRadius` away from this.
     *
     * If `strokeRadius > 0`, the resultant `parameterValue` has no defined value.
     *
     * **Note**: `strokeRadius` is half of a stroke's width.
     */
    intersection(line: LineSegment2, strokeRadius?: number): IntersectionResult[];
    /**
     * @returns the nearest point on this path to the given `point`.
     */
    nearestPointTo(point: Point2): IntersectionResult;
    at(index: CurveIndexRecord): import("../Vec3").Vec3;
    tangentAt(index: CurveIndexRecord): import("../Vec3").Vec3;
    /** Splits this path in two near the given `point`. */
    splitNear(point: Point2, options?: PathSplitOptions): [Path] | [Path, Path];
    /**
     * Returns a copy of this path with `deleteFrom` until `deleteUntil` replaced with `insert`.
     *
     * This method is analogous to {@link Array.toSpliced}.
     */
    spliced(deleteFrom: CurveIndexRecord, deleteTo: CurveIndexRecord, insert: Path | undefined, options?: PathSplitOptions): Path;
    splitAt(at: CurveIndexRecord, options?: PathSplitOptions): [Path] | [Path, Path];
    splitAt(at: CurveIndexRecord[], options?: PathSplitOptions): Path[];
    /**
     * Replaces all `MoveTo` commands with `LineTo` commands and connects the end point of this
     * path to the start point.
     */
    asClosed(): Path;
    private static mapPathCommand;
    mapPoints(mapping: (point: Point2) => Point2): Path;
    transformedBy(affineTransfm: Mat33): Path;
    /**
     * @internal -- TODO: This method may have incorrect output in some cases.
     */
    closedContainsPoint(point: Point2): boolean;
    /**
     * @returns `true` if this path (interpreted as a closed path) contains the given rectangle.
     */
    closedContainsRect(rect: Rect2): boolean;
    union(other: Path | PathCommand[] | null, options?: {
        allowReverse?: boolean;
    }): Path;
    /**
     * @returns a version of this path with the direction reversed.
     *
     * Example:
     * ```ts,runnable,console
     * import {Path} from '@js-draw/math';
     * console.log(Path.fromString('m0,0l1,1').reversed()); // -> M1,1 L0,0
     * ```
     */
    reversed(): Path;
    /** Computes and returns the end point of this path */
    getEndPoint(): import("../Vec3").Vec3;
    /**
     * Like {@link closedRoughlyIntersects} except takes stroke width into account.
     *
     * This is intended to be a very fast and rough approximation. Use {@link intersection}
     * and {@link signedDistance} for more accurate (but much slower) intersection calculations.
     *
     * **Note**: Unlike other methods, this accepts `strokeWidth` (and not `strokeRadius`).
     *
     * `strokeRadius` is half of `strokeWidth`.
     */
    roughlyIntersects(rect: Rect2, strokeWidth?: number): boolean;
    /**
     * Treats this as a closed path and returns true if part of `rect` is *roughly* within
     * this path's interior.
     *
     * **Note**: Assumes that this is a closed, non-self-intersecting path.
     */
    closedRoughlyIntersects(rect: Rect2): boolean;
    /** @returns true if all points on this are equivalent to the points on `other` */
    eq(other: Path, tolerance?: number): boolean;
    /**
     * Returns a path that outlines `rect`.
     *
     * If `lineWidth` is given, the resultant path traces a `lineWidth` thick
     * border around `rect`. Otherwise, the resultant path is just the border
     * of `rect`.
     */
    static fromRect(rect: Rect2, lineWidth?: number | null): Path;
    private cachedStringVersion;
    /**
     * Convert to an [SVG path representation](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths).
     *
     * If `useNonAbsCommands` is given, relative path commands (e.g. `l10,0`) are to be used instead of
     * absolute commands (e.g. `L10,0`).
     *
     * See also {@link fromString}.
     */
    toString(useNonAbsCommands?: boolean, ignoreCache?: boolean): string;
    serialize(): string;
    static toString(startPoint: Point2, parts: PathCommand[], onlyAbsCommands?: boolean): string;
    /**
     * Create a `Path` from a subset of the SVG path specification.
     *
     * Currently, this does not support elliptical arcs or `s` and `t` command
     * shorthands. See https://github.com/personalizedrefrigerator/js-draw/pull/19.
     *
     * @example
     * ```ts,runnable,console
     * import { Path } from '@js-draw/math';
     *
     * const path = Path.fromString('m0,0l100,100');
     * console.log(path.toString(true)); // true: Prefer relative to absolute path commands
     * ```
     */
    static fromString(pathString: string): Path;
    static fromConvexHullOf(points: Point2[]): Path;
    static empty: Path;
}
export default Path;
