§ Единичная матрица
Единичная матрица выглядит так.1identity() { 2 3 return [ 4 [1, 0, 0, 0], 5 [0, 1, 0, 0], 6 [0, 0, 1, 0], 7 [0, 0, 0, 1], 8 ]; 9}При умножении матрицу на единичную матрицу, любая другая матрица равна самой себе.
§ Умножение матриц
Теперь же приведу код для умножения матриц 4x4.1mult(m1, m2) { 2 3 let mat = []; 4 for (let a = 0; a < 4; a++) { 5 6 let row = []; 7 for (let b = 0; b < 4; b++) { 8 9 let s = 0; 10 for (let c = 0; c < 4; c++) s += m1[a][c]*m2[c][b]; 11 row.push(s); 12 } 13 14 mat.push(row); 15 } 16 17 return mat; 18}Пришло время сделать методы для поворотов по X,Y,Z, а также матрицы перемещения (трансляции). На вход подается матрица m, и угол поворота в радианах. Для матрицы трансляции требуется вектор p типа
vec3
.Поворот по оси X
1rotateX(m, angle) { 2 3 let [s,c] = [Math.sin(angle), Math.cos(angle)]; 4 5 return this.mult(m, [ 6 [1, 0, 0, 0], 7 [0, c, -s, 0], 8 [0, s, c, 0], 9 [0, 0, 0, 1] 10 ]); 11}Поворот по оси Y
1rotateY(m, angle) { 2 3 let [s,c] = [Math.sin(angle), Math.cos(angle)]; 4 5 return this.mult(m, [ 6 [ c, 0, s, 0], 7 [ 0, 1, 0, 0], 8 [-s, 0, c, 0], 9 [ 0, 0, 0, 1] 10 ]); 11}Поворот по оси Z
1rotateZ(m, angle) { 2 3 let [s,c] = [Math.sin(angle), Math.cos(angle)]; 4 5 return this.mult(m, [ 6 [c, -s, 0, 0], 7 [s, c, 0, 0], 8 [0, 0, 1, 0], 9 [0, 0, 0, 1] 10 ]); 11}Трансляция матрицы
1translate(m, p) { 2 3 return this.mult(m, [ 4 [1, 0, 0, 0], 5 [0, 1, 0, 0], 6 [0, 0, 1, 0], 7 [p.x, p.y, p.z, 1] 8 ]); 9}
§ Умножение вектора на матрицу
На вход метода поступает m - матрица, и vtx — массив вершин, которые будут преобразованы в новые вершины типа vec3:1matrix_apply(vtx, m) { 2 3 let out = []; 4 for (let i = 0; i < vtx.length; i++) { 5 6 let t = [vtx[i].x, vtx[i].y, vtx[i].z, 1]; 7 let n = [0, 0, 0]; 8 for (let a = 0; a < 3; a++) { 9 10 let s = 0; 11 for (let b = 0; b < 4; b++) s += t[b] * m[b][a]; 12 n[a] = s; 13 } 14 15 out.push( { x:n[0], y:n[1], z:n[2] } ); 16 } 17 18 return out; 19}