-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlinalg.js
More file actions
117 lines (100 loc) · 3.07 KB
/
linalg.js
File metadata and controls
117 lines (100 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
function createIdentityMatrix() {
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
}
function createPerspectiveMatrix(fovy, aspect, znear, zfar) {
const f = 1 / Math.tan((fovy * Math.PI / 180) / 2);
return [f/aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (zfar + znear) / (znear - zfar), -1,
0, 0, (2 * znear * zfar) / (znear - zfar), 0];
}
function createTranslationMatrix(x, y, z) {
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
}
function createScalingMatrix(sx, sy, sz) {
return [sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1]
}
function createRotationMatrix(angle, x, y, z) {
const len = Math.sqrt(x * x + y * y + z * z);
const nx = x / len, ny = y / len, nz = z / len;
const rad = angle * Math.PI / 180;
const c = Math.cos(rad), s = Math.sin(rad);
return [x * x * (1 - c) + c, x * y * (1 - c) + z * s, x * z * (1 - c) - y * s, 0,
x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0,
0, 0, 0, 1];
}
function multMatrix(mat1, mat2) {
let res = new Array(16);
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 4; j++) {
let val = 0;
for (let k = 0; k < 4; k++) {
val += mat1[k * 4 + i] * mat2[j * 4 + k];
}
res[j * 4 + i] = val;
}
}
return res;
}
function invertMatrix(mat) {
let aux = new Array(16);
for (let i = 0; i < 16; i++)
aux[i] = mat[i];
let res = createIdentityMatrix();
for (let j = 0; j < 4; j++) {
const diag = aux[j * 4 + j];
for (let k = 0; k < 4; k++) {
aux[k * 4 + j] /= diag;
res[k * 4 + j] /= diag;
}
for (let i = j + 1; i < 4; i++) {
const leadingCoef = aux[j * 4 + i];
for (let k = 0; k < 4; k++) {
aux[k * 4 + i] -= aux[k * 4 + j] * leadingCoef;
res[k * 4 + i] -= res[k * 4 + j] * leadingCoef;
}
}
}
for (let j = 3; j > 0; j--) {
for (let i = j - 1; i >= 0; i--) {
const leadingCoef = aux[j * 4 + i];
for (let k = 0; k < 4; k++) {
aux[k * 4 + i] -= aux[k * 4 + j] * leadingCoef;
res[k * 4 + i] -= res[k * 4 + j] * leadingCoef;
}
}
}
return res;
}
function multMatrixVec(M, v) {
let res = [0, 0, 0, 0];
for (let i = 0; i < 4; i++) {
for (let k = 0; k < 4; k++) {
res[i] += M[k * 4 + i] * v[k];
}
}
return res;
}
function vectorCrossProduct(v1, v2) {
return [v1[1] * v2[2] - v1[2] * v2[1], v1[2] * v2[0] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]];
}
function vectorDotProduct(v1, v2) {
return (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]);
}
function vectorSubtraction(v1, v2) {
return [v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]];
}
function vectorAddition(v1, v2) {
return [v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]];
}
function vectorScale(v, scalar) {
return [v[0] * scalar, v[1] * scalar, v[2] * scalar];
}
function length(v) {
return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
function normalize(v) {
const len = length(v);
return [v[0] / len, v[1] / len, v[2] / len];
}