/**
 * Matrices 3x3.
 * Definición y operaciones de matrices de transformación 2D.
 * @author Melissa Méndez Servín.
 */
class Matrix3{   
    identity(){
        return [ 1, 0, 0,
                 0, 1, 0,
                 0, 0, 1 ];     
    }
    translate(tx, ty){
        return [ 1, 0, 0,
                 0, 1, 0,
                 tx, ty, 1 ];
    }
    /**
     * 
     * @param {} theta el ángulo en grados
     */
    rotate(theta){
        var thetaToRadians = this.degToRad(theta);
        let cos = Math.cos(thetaToRadians);
        let sin = Math.sin(thetaToRadians);
        return [ cos, sin, 0,
                 -sin,  cos, 0,
                  0 ,   0,  1];
    }
    /**
     * 
     * @param {} theta el ángulo en radianes
     */
    rotateR(theta){
        let cos = Math.cos(theta);
        let sin = Math.sin(theta);
        return [ cos, sin, 0,
                 -sin,  cos, 0,
                  0 ,   0,  1];
    }
    scale(sx, sy){
        return [ sx, 0, 0,
                 0, sy, 0,
                 0, 0, 1 ];   
    }
    /**
     * (AB)^T = B^T * A^T 
     * p_ij = (n_i0 * m_0j) + (n_i1 * m_1j) + (n_i2 * m_2j)
     */
    multiply(m, n){
        var p = [];
        for(var i= 0; i < 3; i++)
            for(var j= 0; j < 3; j++){
                p[3 * i + j] = 0;
                for( var k = 0; k <3; k++)
                    p[3 * i + j] += n[3* i + k] * m[3 * k + j];
            }
        return p;
    }
    degToRad(degrees){
        return degrees * (Math.PI / 180);
    }

    projection(left, right, top, botton){
        return [            2/ (right - left),                               0,  0, 
                                            0,               2/ (top - botton),  0,
                -(right + left)/(right - left), -(top + botton)/(top - botton), 1];
    }

    transpose(m){
        return [m[0], m[3], m[6],
                m[1], m[4], m[7],
                m[2], m[5], m[8]];
    }
    generalMatrix(e1, e2){
        return [ e1.x, e1.y, 0, 
                 e2.x, e2.y, 0,
                 0, 0, 1];
    }
    createMatrix(m){
        return [ m[0], m[3], 0, 
                 m[1], m[4], 0,
                 m[2], m[5], 1];
    }
    getCenterPoint(points){
        var center_x = 0;
        var center_y = 0;
        for(var i= 0; i< points.length; i++){
            if(i % 2 == 0)
                center_x += points[i]/3;
            else
                center_y += points[i]/3;
        }
        return {x: center_x, y: center_y};
    }
    /**
     * V^T * M^T = (M*V)^T
     * @param {*} m 
     * @param {*} v 
     */
    multiplyVector(m,v){
        let u = [];
        for(var i = 0; i < 3; i++){
            u[i] = 0;
            for(var j = 0; j < 3; j++)
                u[i] += v[j] * m[j * 3  + i];
        }
        return u;
    }
}
let M3 = new Matrix3();
export default M3;