// tslint:disable:only-arrow-functions
// tslint:disable:no-conditional-assignment
// tslint:disable:prefer-const
// tslint:disable:no-var-keyword
// tslint:disable:no-inferrable-types

export class Vector {
    public x;
    public y
    constructor(x = 0, y = 0) {
        this.x = x;
        this.y = y;
    }
    initialize() {
        this.x = 0;
        this.y = 0;
    }
    length() {
        return Math.sqrt(this.length2());
    }
    length2() {
        return this.x * this.x + this.y * this.y
    }

    symmetricFromNormalVector(normalVector) {
        var nx2 = normalVector.x * normalVector.x;
        var ny2 = normalVector.y * normalVector.y;
        var nxy = normalVector.x * normalVector.y;
        var tempx = this.x;
        this.x = (2 * this.y * nxy + this.x * (nx2 - ny2)) / (nx2 + ny2);
        this.y = (2 * tempx * nxy - this.y * (nx2 - ny2)) / (nx2 + ny2);
        return this;
    }

    //参数弧度
    rotate(angle) {

        var tempx = this.x;
        this.x = this.x * Math.cos(angle) - this.y * Math.sin(angle)
        this.y = this.y * Math.cos(angle) + tempx * Math.sin(angle);
        return this;
        // function aaa(x,y){
        //     this.x=x;
        //     this.y=y;
        //     this.rotate=function(angle){
        //         var tempx=this.x;
        //         this.x=this.x*Math.cos(angle)-this.y*Math.sin(angle)
        //         this.y=this.y*Math.cos(angle)+tempx*Math.sin(angle);
        //         return this;
        //     }

        // }
    }

    clone() {
        return new Vector(this.x, this.y);
    }

    translate(x, y) {
        this.x += x;
        this.y += y;
        return this;
    }

    //求垂直向量，未归一
    cross() {
        if (this.x == 0) {
            if (this.y == 0) {

            } else {
                this.x = 1;
                this.y = 0;
            }
        } else {
            if (this.y == 0) {
                this.x = 0;
                this.y = 1
            } else {
                var tempx = this.x
                this.x = 1;
                this.y = -tempx / this.y;
            }
        }
        return this;
    }

    //得到向量的长度
    getMagnitude() {
        return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
    }

    //两向量相加得到的新向量
    add(anotherVector) {
        var v = new Vector();
        v.x = this.x + anotherVector.x;
        v.y = this.y + anotherVector.y;
        return v;
    }

    //两向量相减,得到边缘法向量 OA-OB = BA;
    subtract(anotherVector) {
        var v = new Vector();
        v.x = this.x - anotherVector.x;
        v.y = this.y - anotherVector.y;
        return v;
    }

    //两向量的点积，一个向量在别一处向量上的投影,得到的不是一个向量，是投影的长度
    dotProduct(anotherVector) {
        return this.x * anotherVector.x + this.y * anotherVector.y;
    }

    //得到多边形的边缘向量,即多边形，相邻两点的向量
    edge(anotherVector) {
        return this.subtract(anotherVector);
    }

    //得到垂直于边缘向量的边缘法向量，即投影轴向量
    perpendicular() {
        var v = new Vector();
        v.x = this.y;
        v.y = 0 - this.x;
        return v;
    }

    //得去某向量的单位向量，即方向相同，长度为1的向量，单位向量主要是用来指示方向的
    normalize() {
        var v = new Vector(0, 0);
        var m = this.getMagnitude();
        if (m != 0) { //避免向量为0
            v.x = this.x / m;
            v.y = this.y / m;
        }
        return v;
    }

    //得去边缘法向量的单位向量，即投影轴向量的单位方向，表示投影轴的方向
    perpendicularNormal() {
        var p = this.perpendicular();
        return p.normalize();
    }


    //判断向量平行
    parallel(vector) {
        if (Math.abs(this.x * vector.y - this.y * vector.x) < 0.00001) {
            return true
        } else {
            return false
        }
    }


    /**
     * 求与法向量对称的向量
     * @param vector 原向量
     * @param normalVector 法向量
     */
    static symmetricVector(vector, normalVector) {
        var nx2 = normalVector.x * normalVector.x;
        var ny2 = normalVector.y * normalVector.y;
        var nxy = normalVector.x * normalVector.y;
        var x = (2 * vector.y * nxy + vector.x * (nx2 - ny2)) / (nx2 + ny2);
        var y = (2 * vector.x * nxy - vector.y * (nx2 - ny2)) / (nx2 + ny2);
        return new Vector(x, y);
    }
}