/**
 * A vector with three components, $\begin{pmatrix} x \\ y \\ z \end{pmatrix}$.
 * Can also be used to represent a two-component vector.
 *
 * A `Vec3` is immutable.
 *
 * @example
 *
 * ```ts,runnable,console
 * import { Vec3 } from '@js-draw/math';
 *
 * console.log('Vector addition:', Vec3.of(1, 2, 3).plus(Vec3.of(0, 1, 0)));
 * console.log('Scalar multiplication:', Vec3.of(1, 2, 3).times(2));
 * console.log('Cross products:', Vec3.unitX.cross(Vec3.unitY));
 * console.log('Magnitude:', Vec3.of(1, 2, 3).length(), 'or', Vec3.of(1, 2, 3).magnitude());
 * console.log('Square Magnitude:', Vec3.of(1, 2, 3).magnitudeSquared());
 * console.log('As an array:', Vec3.unitZ.asArray());
 * ```
 */
export interface Vec3 {
    readonly x: number;
    readonly y: number;
    readonly z: number;
    /**
     * Returns the x, y components of this.
     * May be implemented as a getter method.
     */
    readonly xy: {
        x: number;
        y: number;
    };
    /** Returns the vector's `idx`th component. For example, `Vec3.of(1, 2, 3).at(1) → 2`. */
    at(i: number): number;
    /** Alias for `.magnitude`. */
    length(): number;
    /** Returns the length of this vector in ℝ^3. */
    magnitude(): number;
    magnitudeSquared(): number;
    /**
     * Interpreting this vector as a point in ℝ^3, computes the square distance
     * to another point, `p`.
     *
     * Equivalent to `.minus(p).magnitudeSquared()`.
     */
    squareDistanceTo(other: Vec3): number;
    /**
     * Interpreting this vector as a point in ℝ³, returns the distance to the point
     * `p`.
     *
     * Equivalent to `.minus(p).magnitude()`.
     */
    distanceTo(p: Vec3): number;
    /**
     * Returns the entry of this with the greatest magnitude.
     *
     * In other words, returns $\max \{ |x| : x \in {\bf v} \}$, where ${\bf v}$ is the set of
     * all entries of this vector.
     *
     * **Example**:
     * ```ts,runnable,console
     * import { Vec3 } from '@js-draw/math';
     * console.log(Vec3.of(-1, -10, 8).maximumEntryMagnitude()); // -> 10
     * ```
     */
    maximumEntryMagnitude(): number;
    /**
     * Return this' angle in the XY plane (treats this as a Vec2).
     *
     * This is equivalent to `Math.atan2(vec.y, vec.x)`.
     *
     * As such, observing that `Math.atan2(-0, -1)` $\approx -\pi$ and `Math.atan2(0, -1)` $\approx \pi$
     * the resultant angle is in the range $[-\pi, \pi]$.
     *
     * **Example**:
     * ```ts,runnable,console
     * import { Vec2 } from '@js-draw/math';
     * console.log(Vec2.of(-1, -0).angle()); // atan2(-0, -1)
     * console.log(Vec2.of(-1, 0).angle());  // atan2(0, -1)
     * ```
     */
    angle(): number;
    /**
     * Returns a unit vector in the same direction as this.
     *
     * If `this` has zero length, the resultant vector has `NaN` components.
     */
    normalized(): Vec3;
    /**
     * Like {@link normalized}, except returns zero if this has zero magnitude.
     */
    normalizedOrZero(): Vec3;
    /** @returns A copy of `this` multiplied by a scalar. */
    times(c: number): Vec3;
    /** Performs vector addition. */
    plus(v: Vec3): Vec3;
    minus(v: Vec3): Vec3;
    /**
     * Computes the scalar product between this and `v`.
     *
     * In particular, `a.dot(b)` is equivalent to `a.x * b.x + a.y * b.y + a.z * b.z`.
     */
    dot(v: Vec3): number;
    /** Computes the cross product between this and `v` */
    cross(v: Vec3): Vec3;
    /**
     * If `other` is a `Vec3`, multiplies `this` component-wise by `other`. Otherwise,
     * if `other is a `number`, returns the result of scalar multiplication.
     *
     * @example
     * ```
     * Vec3.of(1, 2, 3).scale(Vec3.of(2, 4, 6)); // → Vec3(2, 8, 18)
     * ```
     */
    scale(other: Vec3 | number): Vec3;
    /**
     * Returns a vector orthogonal to this. If this is a Vec2, returns `this` rotated
     * 90 degrees counter-clockwise.
     */
    orthog(): Vec3;
    /** Returns this plus a vector of length `distance` in `direction`. */
    extend(distance: number, direction: Vec3): Vec3;
    /** Returns a vector `fractionTo` of the way to target from this. */
    lerp(target: Vec3, fractionTo: number): Vec3;
    /**
     * `zip` Maps a component of this and a corresponding component of
     * `other` to a component of the output vector.
     *
     * @example
     * ```
     * const a = Vec3.of(1, 2, 3);
     * const b = Vec3.of(0.5, 2.1, 2.9);
     *
     * const zipped = a.zip(b, (aComponent, bComponent) => {
     *   return Math.min(aComponent, bComponent);
     * });
     *
     * console.log(zipped.toString()); // → Vec(0.5, 2, 2.9)
     * ```
     */
    zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
    /**
     * Returns a vector with each component acted on by `fn`.
     *
     * @example
     * ```ts,runnable,console
     * import { Vec3 } from '@js-draw/math';
     * console.log(Vec3.of(1, 2, 3).map(val => val + 1)); // → Vec(2, 3, 4)
     * ```
     */
    map(fn: (component: number, index: number) => number): Vec3;
    asArray(): [number, number, number];
    /**
     * @param tolerance The maximum difference between two components for this and [other]
     * to be considered equal.
     *
     * @example
     * ```
     * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 100);  // → true
     * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 0.1);  // → false
     * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3);    // → true
     * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 3.01); // → true
     * Vec3.of(1, 2, 3).eq(Vec3.of(4, 5, 6), 2.99); // → false
     * ```
     */
    eq(other: Vec3, tolerance?: number): boolean;
    toString(): string;
}
declare class Vec2Impl implements Vec3 {
    readonly x: number;
    readonly y: number;
    constructor(x: number, y: number);
    get z(): number;
    get xy(): {
        x: number;
        y: number;
    };
    at(idx: number): number;
    length(): number;
    magnitude(): number;
    magnitudeSquared(): number;
    squareDistanceTo(p: Vec3): number;
    distanceTo(p: Vec3): number;
    maximumEntryMagnitude(): number;
    angle(): number;
    normalized(): Vec3;
    normalizedOrZero(): Vec3;
    times(c: number): Vec3;
    plus(v: Vec3): Vec3;
    minus(v: Vec3): Vec3;
    dot(other: Vec3): number;
    cross(other: Vec3): Vec3;
    scale(other: Vec3 | number): Vec3;
    orthog(): Vec3;
    extend(distance: number, direction: Vec3): Vec3;
    lerp(target: Vec3, fractionTo: number): Vec3;
    zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
    map(fn: (component: number, index: number) => number): Vec3;
    asArray(): [number, number, number];
    eq(other: Vec3, fuzz?: number): boolean;
    toString(): string;
}
/**
 * A `Vec2` is a {@link Vec3} optimized for working in a plane. `Vec2`s have an
 * always-zero `z` component.
 *
 * ```ts,runnable,console
 * import { Vec2 } from '@js-draw/math';
 *
 * const v = Vec2.of(1, 2);
 * console.log('a Vec2:', v);
 * console.log('x component:', v.x);
 * console.log('z component:', v.z);
 * ```
 */
export declare namespace Vec2 {
    /**
     * Creates a `Vec2` from an x and y coordinate.
     *
     * @example
     * ```ts,runnable,console
     * import { Vec2 } from '@js-draw/math';
     * const v = Vec2.of(3, 4); // x=3, y=4.
     * ```
     */
    const of: (x: number, y: number) => Vec2Impl;
    /**
     * Creates a `Vec2` from an object containing `x` and `y` coordinates.
     *
     * @example
     * ```ts,runnable,console
     * import { Vec2 } from '@js-draw/math';
     * const v1 = Vec2.ofXY({ x: 3, y: 4.5 });
     * const v2 = Vec2.ofXY({ x: -123.4, y: 1 });
     * ```
     */
    const ofXY: ({ x, y }: {
        x: number;
        y: number;
    }) => Vec2Impl;
    /** A vector of length 1 in the X direction (→). */
    const unitX: Vec2Impl;
    /** A vector of length 1 in the Y direction (↑). */
    const unitY: Vec2Impl;
    /** The zero vector: A vector with x=0, y=0. */
    const zero: Vec2Impl;
}
/** Contains static methods for constructing a {@link Vec3}. */
export declare namespace Vec3 {
    /**
     * Construct a vector from three components.
     *
     * @example
     * ```ts,runnable,console
     * import { Vec3 } from '@js-draw/math';
     * const v1 = Vec3.of(1, 2, 3);
     * console.log(v1.plus(Vec3.of(0, 100, 0)));
     * ```
     */
    const of: (x: number, y: number, z: number) => Vec3;
    /** A unit vector in the x direction (`[1, 0, 0]`). */
    const unitX: Vec2Impl;
    /** A unit vector in the y direction (`[0, 1, 0]`). */
    const unitY: Vec2Impl;
    /** The zero vector (`[0, 0, 0]`). */
    const zero: Vec2Impl;
    /** A vector of length 1 in the z direction. */
    const unitZ: Vec3;
}
export default Vec3;
