1. 归一化函数
对一个向量进行归一化处理,即调整向量的模长(长度)为1,同时保持其方向不变。
// 归一化函数
function normalized(arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i] * arr[i];
}
const middle = Math.sqrt(sum);
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i] / middle;
}
}
const vector = [3, 4]; // 原始向量
normalized(vector);
console.log(vector); // 输出:[0.6, 0.8],归一化后的向量
2. 叉积
叉积常被用来计算求两个平面的法向量,这个结果向量通常用于确定法线(normal)方向,比如在计算光照效果时。
// 叉积函数,获取法向量,固定写法
function cross(a, b) {
return new Float32Array([
a[1] * b[2] - a[2] * b[1], //这是叉积结果向量的x分量。
a[2] * b[0] - a[0] * b[2], //这是叉积结果向量的y分量。
a[0] * b[1] - a[1] * b[0], //这是叉积结果向量的z分量。
])
}
const a = [1, 2, 3];
const b = [4, 5, 6];
console.log(cross(a, b)); // 结果为[-3, 6, -3]
3. 点积
求某点在x,y,z轴上的投影长度
// 点积函数 获取投影长度
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
const a = [1, 2, 3];
const b = [4, 5, 6];
console.log(dot(a, b)); // 结果为32
4. 向量差
向量差用来获取视点到目标点之间的向量。
// 向量差
function minus(a, b) {
return new Float32Array([
a[0] - b[0],
a[1] - b[1],
a[2] - b[2],
])
}
const a = [1.0, 2.0, 3.0]
const b = [4.0, 5.0, 6.0]
console.log(minus(a, b)) // 结果为[-3.0, -3.0, -3.0]
5. 视图矩阵
基于给定点的视点、注视点和上方向向量来确定视图的方向,并生成相应的矩阵。
// 视图矩阵获取
function getViewMatrix(eyex, eyey, eyez, lookAtx, lookAty, lookAtz, upx, upy, upz) {
// 视点
const eye = new Float32Array([eyex, eyey, eyez])
// 目标点
const lookAt = new Float32Array([lookAtx, lookAty, lookAtz])
// 上方向
const up = new Float32Array([upx, upy, upz])
// 确定z轴
const z = minus(eye, lookAt)
// 确定x轴
normalized(z)
normalized(up)
const x = cross(z, up)
// 确定y轴
normalized(x)
const y = cross(x, z)
return new Float32Array([
x[0], y[0], z[0], 0,
x[1], y[1], z[1], 0,
x[2], y[2], z[2], 0,
-dot(x, eye), -dot(y, eye), -dot(z, eye), 1
])
}
6. 正射投影矩阵
// 获取正射投影矩阵
function getOrtho(l, r, t, b, n, f) {
return new Float32Array([
2 / (r - l), 0, 0, 0,
0, 2 / (t - b), 0, 0,
0, 0, -2 / (f - n), 0,
-(r + l) / (r - l), -(t + b) / (t - b), -(f + n) / (f - n), 1,
])
}
7. 透视投影矩阵
// 获取透视投影矩阵
function getPerspective(fov, aspect, far, near) { //视角,宽高比,远,近
fov = fov * Math.PI / 180;
return new Float32Array([
1 / (aspect * Math.tan(fov / 2)), 0, 0, 0,
0, 1 / (Math.tan(fov / 2)), 0, 0,
0, 0, -(far + near) / (far - near), -(2 * far * near) / (far - near),
0, 0, -1, 0,
])
}