§ Единичная матрица

Единичная матрица выглядит так.
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;
}
24 авг, 2022
© 2007-2022 Разрешил психический человек