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