"use strict";
/**
 * 当向量以数组的方式出现，一个计算单元库
 * @Description  : 向量数组
 * @Author       : 赵耀圣
 * @QQ           : 549184003
 * @Date         : 2021-08-02 15:09:33
 * @LastEditTime : 2021-08-02 15:50:16
 * @FilePath     : \cga.js\src\math\VecArray.ts
 */
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var Polygon_1 = require("../struct/3d/Polygon");
var Polyline_1 = require("../struct/3d/Polyline");
var Vec2_1 = require("./Vec2");
var Vec3_1 = require("./Vec3");
var Vec4_1 = require("./Vec4");
var Math_1 = require("./Math");
var ckeckVec = function (vs, component) {
    if (vs.length % component !== 0)
        throw ("向量组件数量不一样");
};
/**
 * 矢量几何操作，数字数组/矢量数组，常用工具集合
 */
var vector = /** @class */ (function () {
    function vector() {
    }
    /**
     * 去除相邻的重复向量
     * @param vs 矢量集合
     * @param delta 误差
     * @returns
     */
    vector.uniqueNeighborVecs = function (vs, delta) {
        if (delta === void 0) { delta = Math_1.delta4; }
        for (var i = 0; i < vs.length - 1; i++) {
            var lenSq = vs[i].distanceTo(vs[i + 1]);
            if (lenSq < delta)
                vs.splice(i, 1);
        }
        return vs;
    };
    /**
     * 去除相邻没有重复点
     */
    vector.uniqueNeighbor = function (vs, component, delta) {
        if (component === void 0) { component = 3; }
        if (delta === void 0) { delta = Math_1.delta4; }
        for (var i = 0; i < vs.length; i += component) {
            for (var j = i + 3; j < vs.length;) {
                var lensq = 0;
                for (var c = 0; c < component; c++) {
                    lensq += (vs[i + c] - vs[j + c]) * (vs[i + c] - vs[j + c]);
                }
                if (Math.sqrt(lensq) < delta)
                    vs.splice(j, component);
                else
                    break;
            }
        }
        return vs;
    };
    /**
     * 去除任意重复点
     * @param vs 向量数组
     * @param component 向量组件数量
     * @returns 无重复向量数组
     */
    vector.unique = function (vs, component) {
        if (component === void 0) { component = 3; }
        for (var i = 0; i < vs.length; i += component) {
            for (var j = i + 3; j < vs.length;) {
                var lensq = 0;
                for (var c = 0; c < component; c++) {
                    lensq += (vs[i + c] - vs[j + c]) * (vs[i + c] - vs[j + c]);
                }
                if (Math.sqrt(lensq) < 1e-5)
                    vs.splice(j, component);
                else
                    j += component;
            }
        }
        return vs;
    };
    /**
     *  翻转向量数组
     * @param vecs 向量数组
     * @param component  组件数量
     * @returns
     */
    vector.reverse = function (vecs, component) {
        if (component === void 0) { component = 3; }
        ckeckVec(vecs, component);
        var length = vecs.length;
        for (var i = 0; i < length; i += component) {
            vecs.unshift.apply(vecs, vecs.splice(i, component));
        }
        return vecs;
    };
    /**
     * 点积
     * @param vecs
     * @returns
     */
    vector.dot = function () {
        var vecs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            vecs[_i] = arguments[_i];
        }
        if (vecs.length % 2 !== 0)
            throw ("两个向量组件数量不一样");
        var len = vecs.length / 2;
        var dot = 0;
        for (var i = 0; i < len; i++) {
            dot += vecs[i] * vecs[len + i];
        }
        return dot;
    };
    /**
     * 长度平方
     * @param vecs
     * @returns
     */
    vector.distanceSq = function () {
        var vecs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            vecs[_i] = arguments[_i];
        }
        if (vecs.length % 2 !== 0)
            throw ("向量组件数量不一样");
        var len = vecs.length / 2;
        var lenSq = 0;
        for (var i = 0; i < len; i++) {
            var d = (vecs[i] - vecs[len + i]);
            lenSq += d * d;
        }
        return lenSq;
    };
    /**
     * 长度
     * @param vecs
     * @returns
     */
    vector.distance = function () {
        var vecs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            vecs[_i] = arguments[_i];
        }
        return Math.sqrt(this.distanceSq.apply(this, vecs));
    };
    /**
     * 相加
     * @param vecs
     * @returns
     */
    vector.add = function () {
        var vecs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            vecs[_i] = arguments[_i];
        }
        if (vecs.length % 2 !== 0)
            throw ("两个向量组件数量不一样");
        if (Array.isArray(vecs[0]) && Array.isArray(vecs[1])) {
            for (var i = 0; i < vecs[0].length; i++) {
                vecs[0][i] += vecs[1][i];
            }
            return vecs[0];
        }
        if (vecs.length % 2 !== 0)
            console.error("VecArray:distanceSq  向量错误!!!");
        var len = vecs.length / 2;
        var res = [];
        for (var i = 0; i < len; i++) {
            res[i] = res[len + i] + res[i];
        }
        return res;
    };
    /**
     * 相减
     * @param vecs
     * @returns
     */
    vector.sub = function () {
        var vecs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            vecs[_i] = arguments[_i];
        }
        ckeckVec(vecs, 2);
        if (Array.isArray(vecs[0]) && Array.isArray(vecs[1])) {
            for (var i = 0; i < vecs[0].length; i++) {
                vecs[0][i] -= vecs[1][i];
            }
            return vecs[0];
        }
        if (vecs.length % 2 !== 0)
            console.error("VecArray:distanceSq  向量错误!!!");
        var len = vecs.length / 2;
        var res = [];
        for (var i = 0; i < len; i++) {
            res[i] = res[i] - res[len + i];
        }
        return res;
    };
    /**
     * 相乘
     * @param vecs
     * @returns
     */
    vector.mul = function () {
        var vecs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            vecs[_i] = arguments[_i];
        }
        ckeckVec(vecs, 2);
        if (Array.isArray(vecs[0]) && Array.isArray(vecs[1])) {
            for (var i = 0; i < vecs[0].length; i++) {
                vecs[0][i] *= vecs[1][i];
            }
            return vecs[0];
        }
        if (vecs.length % 2 !== 0)
            console.error("VecArray:distanceSq  向量错误!!!");
        var len = vecs.length / 2;
        var res = [];
        for (var i = 0; i < len; i++) {
            res[i] = res[i] * res[len + i];
        }
        return res;
    };
    /**
     * 获取矢量数组的i个矢量
     * @param vecs
     * @param i
     * @param component
     * @returns
     */
    vector.getVecAt = function (vecs, i, component) {
        if (component === void 0) { component = 3; }
        return [vecs[3 * i], vecs[3 * i + 1], vecs[3 * i + 2]];
    };
    /**
     * 在第 i 个位置插入一个向量
     * @param vecs
     * @param i
     * @param vec
     */
    vector.insertAt = function (vecs, i) {
        var vec = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            vec[_i - 2] = arguments[_i];
        }
        vecs.splice.apply(vecs, __spreadArrays([i * vecs.length, 0], vecs));
    };
    //
    /**
     * 是否逆时针
     * counterclockwise
     */
    vector.isCCW = function (shape, component) {
        if (component === void 0) { component = 3; }
        var d = 0;
        if (shape instanceof Polyline_1.Polyline || shape instanceof Polygon_1.Polygon)
            for (var i = 0; i < shape.length; i++) {
                var pt = shape.get(i);
                var ptnext = shape.get((i + 1) % shape.length);
                d += -0.5 * (ptnext.y + pt.y) * (ptnext.x - pt.x);
            }
        else if (Array.isArray(shape) && shape.length > 0) {
            if (shape[0] instanceof Vec3_1.Vec3 || shape[0] instanceof Vec2_1.Vec2) {
                for (var i = 0; i < shape.length; i++) {
                    var pt = shape[i];
                    var ptnext = shape[(i + 1) % shape.length];
                    d += -0.5 * (ptnext.y + pt.y) * (ptnext.x - pt.x);
                }
            }
            else if (!isNaN(shape[0])) {
                for (var i = 0; i < shape.length; i += component) {
                    var ptx = shape[i];
                    var pty = shape[(i + 1) % shape.length];
                    var ptnextx = shape[(i + 3) % shape.length];
                    var ptnexty = shape[(i + 4) % shape.length];
                    d += -0.5 * (ptnexty + pty) * (ptnextx - ptx);
                }
            }
        }
        return d > 0;
    };
    /**
     * 将向量深度拆解为数字
     * @param {Array} Array<Vec4 | Vec3 | Vec2 | any> | any
     * @param {String} comSort  'x','y','z','w' 按顺序选取后自由组合
     * @returns {Array<Number>} 数字数组
     */
    vector.verctorToNumbers = function (vecs, comSort) {
        if (comSort === void 0) { comSort = "xyz"; }
        if (!(vecs instanceof Array)) {
            console.error("传入参数必须是数组");
            return [];
        }
        var numbers = [];
        if (vecs[0].x !== undefined && vecs[0].y !== undefined && vecs[0].z !== undefined && vecs[0].w !== undefined) {
            comSort = comSort.length !== 4 ? 'xyzw' : comSort;
            for (var i = 0; i < vecs.length; i++) {
                for (var j = 0; j < comSort.length; j++) {
                    numbers.push(vecs[i][comSort[j]]);
                }
            }
        }
        if (vecs[0].x !== undefined && vecs[0].y !== undefined && vecs[0].z !== undefined) {
            comSort = comSort.length !== 3 ? 'xyz' : comSort;
            for (var i = 0; i < vecs.length; i++) {
                for (var j = 0; j < comSort.length; j++) {
                    numbers.push(vecs[i][comSort[j]]);
                }
            }
        }
        else if (vecs[0].x !== undefined && vecs[0].y !== undefined) {
            comSort = comSort.length !== 2 ? 'xy' : comSort;
            for (var i = 0; i < vecs.length; i++) {
                for (var j = 0; j < comSort.length; j++) {
                    numbers.push(vecs[i][comSort[j]]);
                }
            }
        }
        else if (vecs[0] instanceof Array) {
            for (var i = 0; i < vecs.length; i++) {
                numbers = numbers.concat(vector.verctorToNumbers(vecs[i]));
            }
        }
        else {
            console.error("数组内部的元素不是向量");
        }
        return numbers;
    };
    vector.vec = function (component) {
        if (component === void 0) { component = 3; }
        if (component === 2)
            return new Vec2_1.Vec2;
        if (component === 3)
            return new Vec3_1.Vec3;
        if (component === 4)
            return new Vec4_1.Vec4;
        throw ('暂时不支持4维以上的矢量');
    };
    /**
     * 数字数组 转 适量数组
     * @param vss  数字数组
     * @param component 矢量维度，默认为3
     * @returns
     */
    vector.numbersToVecs = function (vss, component) {
        if (component === void 0) { component = 3; }
        var result = [];
        var length = vss.length;
        for (var i = 0; i < length; i += component) {
            var vec = vector.vec(component);
            vec.fromArray(vss.slice(i, i + component));
            result.push(vec);
        }
        return result;
    };
    return vector;
}());
exports.default = vector;
