矩阵就是一个按照长方形排列的数表,本质上就是一个二维数组。
将m x n 个元素按 m 行,n 列的方式排列,可用下面的方式表示:
A=a11a21⋮am1a12a22⋮am2⋯⋯⋱⋯a1na2n⋮amn
常见的有:2x2,3x3,4x4等。
矩阵可用来表示线性变换,图形学中的平移、缩放、旋转、投影、相机视角等变换,全靠矩阵。
矩阵加减法计算是在矩阵对应位置上元素的加减法计算,结果还是一个矩阵。
假设有两个3x3矩阵 A 和 B,它们的加法计算公式为:
A+B=a11a21a31a12a22a32a13a23a33+b11b21b31b12b22b32b13b23b33=a11+b11a21+b21a31+b31a12+b12a22+b22a32+b32a13+b13a23+b23a33+b33
它们的减法公式为:
A−B=a11a21a31a12a22a32a13a23a33+b11b21b31b12b22b32b13b23b33=a11−b11a21−b21a31−b31a12−b12a22−b22a32−b32a13−b13a23−b23a33−b33
注意:
- 只有相同维度的矩阵才能进行加减法运算
- 矩阵加法使用交换律和结合律:A + B = B + A;(A + B) + C = A + (B + C)
GLSL示例:
mat3 A = mat3(
1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0
);
mat3 B = mat3(
9.0, 8.0, 7.0,
6.0, 5.0, 4.0,
3.0, 2.0, 1.0
);
mat3 C = A + B; // mat(10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0)
mat3 D = A - B; // mat(-8.0, -6.0, -4.0, -2.0, 0.0, 2.0, 4.0, 6.0, 8.0)
矩阵的数乘就是用一个数(标量)去乘m x n矩阵的所有元素,结果还是一个m x n矩阵。
kA=ka11a21a31a12a22a32a13a23a33=ka11ka21ka31ka12ka22ka32ka13ka23ka33
几何意义:矩阵本身可以看作是一种“空间变换规则”,例如矩阵S,对它数乘一个系数 k=2后:
2S=2200030001=400060002
矩阵 S 是一个缩放矩阵,表示:在x方向缩放 2 倍,在y方向缩放 3 倍,在z方向不变。数乘 2 之后,表示x方向缩放4倍,y方向缩放6倍,z方向缩放2倍。这说明数乘改变了缩放比例,整体放大了原变换的强度。
注:
- 矩阵数乘满足分配律:(k + v) A = kA + vA; k(A + B) = kA + kB
- 矩阵数乘满足结合律:(kv)A = k(vA)
ThreeJS示例:
const m = new THREE.Matrix3().set(
1, 2, 3,
4, 5, 6,
7, 8, 9
)
m.multiplyScalar(2)
console.log(m.elements) // [2, 4, 6, 8, 10, 12, 14, 16, 18]
GLSL示例:
const m = new THREE.Matrix3().set(
1, 2, 3,
4, 5, 6,
7, 8, 9
)
m.multiplyScalar(2)
console.log(m.elements) // [2, 4, 6, 8, 10, 12, 14, 16, 18]
矩阵转置是将一个矩阵的行列互换的操作,一个mxn的矩阵转置后,得到的结果是一个nxm的矩阵。
(AT)ij=Aji
A=a11a21a31a12a22a32a13a23a33,AT=a11a12a13a21a22a23a31a32a33
例如:
A=[142536]2×3,AT=1234563×3
注:
- 转置的转置:(AT)T=A
- 和的转置:(A+B)T=AT+BT
- 数乘的转置:(kA)T=kAT
- 乘法的转置(注意顺序反转):(AB)T=BTAT
Three.js 示例:
const m = new THREE.Matrix3();
m.set(1, 2, 3, 4, 5, 6, 7, 8, 9)
const n = m.clone().transpose()
console.log(m.elements) // [1, 4, 7, 2, 5, 8, 3, 6, 9]
console.log(n.elements) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
GLSL 示例:
mat3 m = mat3(
1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0
);
mat3 t = transpose(m);
两个矩阵相乘必须满足一个条件:被乘矩阵的列数等于乘数矩阵的行数,如果矩阵A的大小是 m x n,矩阵B的大小是 n x p,那么它们的乘积 C = A x B 就是一个 m x p 大小的矩阵。即:前一个矩阵的列数 = 后一个矩阵的行数,才能相乘。
3 x 3矩阵的计算公式如下:
C=A×B=a11a21a31a12a22a32a13a23a33×b11b21b31b12b22b32b13b23b33=a11b11+a12b21+a13b31a21b11+a22b21+a23b31a31b11+a32b21+a33b31a11b12+a12b22+a13b32a21b12+a22b22+a23b32a31b12+a32b22+a33b32a11b13+a12b23+a13b33a21b13+a22b23+a23b33a31b13+a32b23+a33b33
即
C=c11c21c31c12c22c32c13c23c33,cij=k=1∑3aikbkj
C 也是一个 3x3 矩阵,每个元素的计算公式为:
cij=ai1b1j+ai2b2j+ai3b3j,i,j=1,2,3
记忆技巧:结果矩阵的每个元素 Cij 等于 A 的第 i 行与 B 的第 j 列对应元素乘积之和。
一般形式的公式为:
设:
A=[aik]m×p,B=[bkj]p×n,C=AB=[cij]m×n
每个元素的公式是:
cij=k=1∑paikbkj,i=1,…,m,j=1,…,n
注:
- 矩阵相乘满足分配律:A(B + C) = AB + AC, (A + B)C = AC + BC
- 满足结合律:(AB)C = A(BC)
- 满足标量结合律:k(AB) = (kA)B = A(kB)
- 不满足交换律,顺序很重要:AB ≠ BA
Three.js 示例:
// A 矩阵
const A = new THREE.Matrix3().set(
1, 2, 3,
4, 5, 6,
7, 8, 9
);
// B 矩阵
const B = new THREE.Matrix3().set(
9, 8, 7,
6, 5, 4,
3, 2, 1
);
// C = A × B
const C = new THREE.Matrix3().copy(A).multiply(B);
console.log(C.elements);
// [1*9+2*6+3*3, 1*8+2*5+3*2, 1*7+2*4+3*1
// 4*9+5*6+6*3, 4*8+5*5+6*2, 4*7+5*4+6*1
// 7*9+8*6+9*3, 7*8+8*5+9*2, 7*7+8*4+9*1]
//[ 30, 24, 18,
// 84, 69, 54,
// 138, 114, 90]
GLSL 示例:
mat3 A = mat3(
1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0
);
mat3 B = mat3(
9.0, 8.0, 7.0,
6.0, 5.0, 4.0,
3.0, 2.0, 1.0
);
// 矩阵相乘
mat3 C = A * B;
任何一个向量都可以用一维矩阵表示,行向量可以看成一个1xn的矩阵(一行n列),列向量可以看成是一个mx1的矩阵(m行一列)。
根据两个矩阵可以相乘的条件,矩阵和向量相乘有两种形式:
-
列向量形式:如果 x 是列向量 (n×1),常见的乘法是:
Am×n⋅xn×1=ym×1
结果是一个mx1的列向量,这是最常用的「矩阵乘向量」。
-
行向量形式:如果 xT是行向量 (1×m),那么它可以乘在矩阵的左边:
x1×mT⋅Am×n=y1×nT
结果是一个1xn的行向量。
计算过程可以参考矩阵相乘的过程,但只需更少的计算,比如:
y=Ax=a11a21a31a12a22a32a13a23a33⋅x1x2x3=a11x1+a12x2+a13x3a21x1+a22x2+a23x3a31x1+a32x2+a33x3
几何意义:可以把矩阵看成一个线性变换,它把一个向量映射为一个新的向量。如在计算机图形学中,旋转或缩放矩阵作用在向量上得到旋转或缩放后的向量,投影矩阵作用在向量上得到投影坐标。
Three.js 示例:
const m = new THREE.Matrix3().set(
1, 2, 3,
4, 5, 6,
7, 8, 9
)
const v = new THREE.Vector3(1, 2, 3)
// y = m * v
const result = v.clone().applyMatrix3(m)
console.log(result) // {x: 14, y: 32, z: 50}
// {x: 1*1+2*2+3*3, y: 4*1+5*2+6*3, z: 7*1+8*2+9*3}
GLSL 示例:
mat3 m = mat3(
1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0
);
vec3 v = vec3(1.0, 2.0, 3.0);
vec3 y = m * v;
-
方阵(Square Matrix):行数与列数相同,常用于线性变换、特征值、逆矩阵等。
-
零矩阵(Zero Matrix):所有元素都为 0。
-
单位矩阵(Identity Matrix):对角线为 1,其余为 0。
In=100010001
-
对角矩阵(Diagonal Matrix):也是缩放矩阵,仅主对角线上有元素。运算简单、常用于缩放变换。
D=d1000d2000d3