export class Vector3 {
    /**
     * 
     * @param {number} x 
     * @param {number} y 
     * @param {number} z 
     */
    constructor(x, y, z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    /**
     * @param {Vector3} other
     */
    equals(other) {
        return this.x === other.x && this.y === other.y && this.z === other.z;
    }

    /**
     * @param {Vector3} other
     */
    add(other) {
        return new Vector3(this.x + other.x, this.y + other.y, this.z + other.z);
    }

    /**
     * @param {Vector3} other
     */
    subtract(other) {
        return new Vector3(this.x - other.x, this.y - other.y, this.z - other.z);
    }

    /**
     * @param {number} scalar
     */
    multiply(scalar) {
        return new Vector3(this.x * scalar, this.y * scalar, this.z * scalar);
    }

    /**
     * @param {number} divisor
     */
    divide(divisor) {
        return new Vector3(this.x / divisor, this.y / divisor, this.z / divisor);
    }

    /**
     * 
     * @returns {Vector3}
     */
    clone() {
        return new Vector3(this.x, this.y, this.z);
    }

    /**
     * 
     * @param {Vector3} other 
     * @param {number} points
     * @returns {Vector3[]}
     */
    lerp(other, points) {
        const step = 1 / points;
        const lerped = [];
        for (let i = 0; i < points; i++) {
            lerped.push(this.add(other.subtract(this).multiply(step * i)));
        }
        return lerped;
    }

    /**
     * 
     * @param {Vector3} vec 
     * @returns {Vector3}
     */
    toVector(vec) {
        return new Vector3(vec.x, vec.y, vec.z)
    }

    /**
     * 
     * @param {Vector3} vec 
     * @returns {number}
     */
    distance(vec) {
        return Math.sqrt(Math.pow(this.x - vec.x, 2) + Math.pow(this.y - vec.y, 2) + Math.pow(this.z - vec.z, 2));
    }

    /**
     * 
     * @param {number} decimalPlaces 
     * @returns {Vector3}
     */
    rounded(decimalPlaces) {
        const factor = Math.pow(10, decimalPlaces);
        return new Vector3(Math.round(this.x * factor) / factor, Math.round(this.y * factor) / factor, Math.round(this.z * factor) / factor);
    }

    /**
     * 
     * @returns {string}
     */
    toString() {
        return `(${this.x}, ${this.y}, ${this.z})`;
    }
}