import type { Point3 } from '../../types';
import { type Vector } from './Vector';
type Vec3 = Vector3 | Point3;
/**
 * Utility class for manipulating a 3D vectors
 *
 * @exports
 * @class Vector3
 * @implements Vector
 */
export default class Vector3 implements Vector<Vec3> {
    readonly isVector3 = true;
    readonly type: string;
    /**
     * X-axis value of this vector
     */
    x: number;
    /**
     * Y-axis value of this vector
     */
    y: number;
    /**
     * Z-axis value of this vector
     */
    z: number;
    [Symbol.iterator](): Iterator<number>;
    /**
     * @param {number} [x=0] X-axis value
     * @param {number} [y=0] Y-axis value
     * @param {number} [z=0] Z-axis value
     */
    constructor(x?: number, y?: number, z?: number);
    /**
     * Set this vector values
     *
     * @param {number} x X-axis value
     * @param {number} y Y-axis value
     * @param {number} z Z-axis value
     * @returns {this}
     */
    set(x: number, y: number, z: number): this;
    /**
     * Set a given scalar value to all values of this vector
     *
     * @param {number} scalar Value to set for all vector values
     * @returns {this}
     */
    setScalar(scalar: number): this;
    /**
     * Set this vector X-axis value
     *
     * @param {number} x X-axis value to set
     * @returns {this}
     */
    setX(x: number): this;
    /**
     * Set this vector Y-axis value
     *
     * @param {number} y Y-axis value to set
     * @returns {this}
     */
    setY(y: number): this;
    /**
     * Set this vector Z-axis value
     *
     * @param {number} z Z-axis value to set
     * @returns {this}
     */
    setZ(z: number): this;
    /**
     * Set a given value of this vector
     *
     * @param {string|number} index `0` equals to `x`, `1` equals to `y`, `2` equals to `z`
     * @param {number} value Value to set
     * @returns {this}
     */
    setValue(index: 'x' | 'y' | 'z' | number, value: number): this;
    /**
     * Return a value from the vector
     *
     * @param {string|number} index `0` equals to `x`, `1` equals to `y`, `2` equals to `z`
     * @returns {number}
     */
    getValue(index: 'x' | 'y' | 'z' | number): number;
    /**
     * Add a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to add
     * @returns {this}
     */
    add([x, y, z]: Vec3): this;
    /**
     * Add a given scalar value to all values of this vector
     *
     * @param {number} scalar Scalar value to add
     * @returns {this}
     */
    addScalar(scalar: number): this;
    /**
     * Subtract a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to subtract
     * @returns {this}
     */
    sub([x, y, z]: Vec3): this;
    /**
     * Subtract a given scalar value to all values of this vector
     *
     * @param {number} scalar Scalar value to subtract
     * @returns {this}
     */
    subScalar(scalar: number): this;
    /**
     * Multiply a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to multiply
     * @returns {this}
     */
    multiply([x, y, z]: Vec3): this;
    /**
     * Multiply a given scalar value to all values of this vector
     *
     * @param {number} scalar Scalar value to multiply
     * @returns {this}
     */
    multiplyScalar(scalar: number): this;
    /**
     * Divide a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to divide
     * @returns {this}
     */
    divide([x, y, z]: Vec3): this;
    /**
     * Divide a given scalar value to all values of this vector
     *
     * @param {number} scalar Scalar value to multiply
     * @returns {this}
     */
    divideScalar(scalar: number): this;
    /**
     * Set this vector values to the min values compared to a given vector
     *
     * @param {Vector3|Point3} vector Vector to compare values with
     * @returns {this}
     */
    min([x, y, z]: Vec3): this;
    /**
     * Set this vector values to the max values compared to a given vector
     *
     * @param {Vector3|Point3} vector Vector to compare values with
     * @returns {this}
     */
    max([x, y, z]: Vec3): this;
    /**
     * Clamp this vector values to given boundaries
     *
     * @param {Vector3|Point3} min Minimum boundaries
     * @param {Vector3|Point3} max Maximum boundaries
     * @returns {this}
     */
    clamp([minX, minY, minZ]: Vec3, [maxX, maxY, maxZ]: Vec3): this;
    /**
     * Clamp this vector values to given scalar values
     *
     * @param {Vector3|Point3} min Minimum scalar boundary
     * @param {Vector3|Point3} max Maximum scalar boundary
     * @returns {this}
     */
    clampScalar(min: number, max: number): this;
    /**
     * Round down to the nearest integer value this vector values
     *
     * @returns {this}
     */
    floor(): this;
    /**
     * Round up to the nearest integer value this vector values
     *
     * @returns {this}
     */
    ceil(): this;
    /**
     * Round to the nearest integer value this vector values
     *
     * @returns {this}
     */
    round(): this;
    /**
     * Remove any fractional digits of this vector values
     *
     * @returns {this}
     */
    trunc(): this;
    /**
     * Set this vector values to their negative values
     *
     * @returns {this}
     */
    negate(): this;
    /**
     * Linearly interpolate this vector values towards a given vector values
     *
     * @param {number} t Normalized time value to interpolate
     * @param {Vector3|Point3} vector Vector to interpolate values towards
     * @returns {this}
     */
    lerp(t: number, [x, y, z]: Vec3): this;
    /**
     * Convert this vector to a unit vector
     *
     * @returns {this}
     */
    normalize(): this;
    /**
     * Transform this vector by a given matrix
     *
     * @param {DOMMatrix} matrix Matrix to apply
     * @returns {this}
     */
    applyMatrix(matrix: DOMMatrix): this;
    /**
     * Set this vector values to the same direction but with a given length
     *
     * @param {number} length Length value
     * @returns {this}
     */
    setLength(length: number): this;
    /**
     * Project this vector onto a given vector
     *
     * @param {Vector3|Point3} vector Vector to project to
     * @returns {this}
     */
    projectOnVector(vector: Vec3): this;
    /**
     * Compute the Euclidean length of this vector
     *
     * @returns {number} Computed Euclidean length
     */
    length(): number;
    /**
     * Compute the squared length of this vector
     *
     * @return {number} Computed squared length
     */
    squaredLength(): number;
    /**
     * Compute the Manhattan length of this vector
     *
     * @return {number} Computed Manhattan length
     */
    manhattanLength(): number;
    /**
     * Check if this vector is equal with a given vector
     *
     * @param {Vector3|Point3} vector Vector to check
     * @returns {boolean} `true` if this vector is equal with the given vector, `false` otherwise
     */
    equals(vector: Vec3): boolean;
    /**
     * Check if this vector is collinear with a given vectors
     *
     * @param {Vector3|Point3} vector1 First vector to check
     * @param {Vector3|Point3} vector2 Second vector to check
     * @returns {boolean} `true` if this vector is collinear with the given vectors, `false` otherwise
     */
    collinear(vector1: Vec3, vector2: Vec3): boolean;
    /**
     * Compute the dot product of a given vector with this vector
     *
     * @param {Vector3|Point3} vector Vector to compute the dot product with
     * @returns {number} Computed dot product
     */
    dot(vector: Vec3): number;
    /**
     * Compute the cross product of a given vector with this vector
     *
     * @param {Vector3|Point3} vector Vector to compute the cross product with
     * @returns {Point3} Computed cross product
     */
    cross(vector: Vec3): Point3;
    /**
     * Compute the angle between a given vector and this vector
     *
     * @param {Vector3|Point3} vector Vector to compute the angle with
     * @returns {number} Computed angle (in radians)
     */
    angleTo(vector: Vec3): number;
    /**
     * Compute the Euclidean distance from a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to compute the distance to
     * @returns {number} Computed Euclidean distance
     */
    distanceTo(vector: Vec3): number;
    /**
     * Compute the squared distance from a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to compute the squared distance to
     * @returns {number} Computed squared distance
     */
    squaredDistanceTo(vector: Vec3): number;
    /**
     * Compute the Manhattan distance from a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to compute the Manhattan distance to
     * @returns {number} Computed Manhattan distance
     */
    manhattanDistanceTo(vector: Vec3): number;
    /**
     * Return this vector values into an array
     *
     * @returns {Point3}
     */
    toArray(): Point3;
    /**
     * Set this vector values from a given array
     *
     * @param {number[]} values Values to set
     * @returns
     */
    fromArray([x, y, z]: number[]): this;
    /**
     * Set this vector values from given spherical coordinates
     *
     * @param {number} phi   Polar angle from the y (up) axis     : [0, PI]
     * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
     * @param {number} [radius] Radius of the sphere
     * @returns {this}
     */
    fromSphericalCoords(phi: number, theta: number, radius?: number): this;
    /**
     * Set this vector values from given cylindrical coordinates
     *
     * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
     * @param {number} y     Y-axis value
     * @param {number} [radius] Radius of the cylinder
     * @returns {this}
     */
    fromCylindricalCoords(theta: number, y: number, radius?: number): this;
    /**
     * Copy the values of a given vector to this vector
     *
     * @param {Vector3|Point3} vector Vector to copy values from
     * @returns {this}
     */
    copy([x, y, z]: Vec3): this;
    /**
     * Create a new 3D vector with copied values from this vector
     *
     * @returns {Vector3}
     */
    clone(): Vector3;
    /**
     * Add two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {Point3}
     */
    static add([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): Point3;
    /**
     * Subtract two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {Point3}
     */
    static sub([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): Point3;
    /**
     * Multiply two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {Point3}
     */
    static multiply([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): Point3;
    /**
     * Divide two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {Point3}
     */
    static divide([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): Point3;
    /**
     * Linearly interpolate a point between two vectors
     *
     * @param {number} t Normalized time value to interpolate
     * @param {Vector3|Point3} min Minimum boundaries
     * @param {Vector3|Point3} max Maximum boundaries
     * @returns {Point3}
     */
    static lerp(t: number, [x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): Point3;
    /**
     * Check if two vectors are equal to each other
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {boolean} `true` if the given vectors are equal, `false` otherwise
     */
    static equals([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): boolean;
    /**
     *  Check if three vectors are collinear (aligned on the same line)
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @param {Vector3|Point3} vector3 Third vector
     * @returns {boolean} `true` if the given vectors are collinear, `false` otherwise
     */
    static collinear([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3, [x3, y3, z3]: Vec3): boolean;
    /**
     * Compute the dot product of two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {number} Computed dot product
     */
    static dot([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): number;
    /**
     * Compute the cross product of two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {Point3} Computed cross product
     */
    static cross([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): Point3;
    /**
     * Compute the Euclidean distance between two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {number} Computed Euclidean distance
     */
    static distance(vector1: Vec3, vector2: Vec3): number;
    /**
     * Compute the squared distance between two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @returns {number} Computed squared distance
     */
    static squaredDistance([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): number;
    /**
     * Compute the Manhattan distance between two vectors
     *
     * @param {Vector3|Point3} vector1 First vector
     * @param {Vector3|Point3} vector2 Second vector
     * @return {number} Computed Manhattan distance
     */
    static manhattanDistance([x1, y1, z1]: Vec3, [x2, y2, z2]: Vec3): number;
    /**
     * Compute the Euclidean length of a vector
     *
     * @param {Vector3|Point3} vector Vector to compute Euclidean length from
     * @returns {number} Computed Euclidean length
     */
    static length(vector: Vec3): number;
    /**
     * Compute the squared length of a vector
     *
     * @param {Vector3|Point3} vector Vector to compute squared length from
     * @returns {number} Computed squared length
     */
    static squaredLength([x, y, z]: Vec3): number;
    /**
     * Compute the Manhattan length of a vector
     *
     * @param {Vector3|Point3} vector Vector to compute Manhattan length from
     * @return {number} Computed Manhattan length
     */
    static manhattanLength([x, y, z]: Vec3): number;
    /**
     * Convert spherical coordinates to a 3D point on the surface of a sphere
     *
     * @param {number} phi   Polar angle from the y (up) axis     : [0, PI]
     * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
     * @param {number} [radius=1] Radius of the sphere
     * @returns {Point3}
     */
    static fromSphericalCoords(phi: number, theta: number, radius?: number): Point3;
    /**
     * Convert cylindrical coordinates to a 3D point on the surface of a cylinder
     *
     * @param {number} theta Equator angle around the y (up) axis : [0, 2*PI]
     * @param {number} y     Y-axis value
     * @param {number} [radius=1] Radius of the cylinder
     * @returns {Point3}
     */
    static fromCylindricalCoords(theta: number, y: number, radius?: number): Point3;
}
export {};
