【数学】矩阵

【数学】矩阵

数学上,一个 m × n 的矩阵是指一个有 m 行 n 列元素的矩形阵列。

A=[a11a12a1na21a22a2nam1am2amn]A= \begin{bmatrix} a_{11} & a_{12} & \dots & a_{1n} \\ a_{21} & a_{22} & \dots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \dots & a_{mn} \\ \end{bmatrix}

矩阵的作用

  1. 表示一个空间

    矩阵由多个基向量构成,恰巧可以描述一个多维空间。

  2. 表示一种变换

    当矩阵的基向量本质是另一个空间的向量时,该矩阵的向量,也可以重新转换回基向量所在的空间,这个过程就叫变换。

    例如:物体空间实际是利用物体在世界空间中的三个向量组成的新空间,该空间矩阵可与其向量做乘法运算,使其向量转换回世界空间。

所以根据上述内容的分析可以得出常见矩阵之间的关系:

物体空间矩阵=物体变换矩阵=物体到世界空间变换矩阵。物体空间矩阵=物体变换矩阵=物体到世界空间变换矩阵。

矩阵的运算

余子式

将矩阵中某些行或列去除后,剩下的元素组成的新矩阵。

  • k 阶余子式

    去除行或列的数量被称为余子式的阶数。

    对于 1 阶余子式通常记作MijM_{ij},表示去除了 i 行 j 列。

  • 代数余子式

    一种拥有正负号的余子式叫做代数余子式,其正负号是通过移除的行列序号判断的。

    MijM_{ij}的代数余子式记作 Cij=(1)i+jMijC_{ij} = (-1)^{i+j} M_{ij}

行列式

输入一个矩阵,输出一个标量。记作 det(A)det(A)A|A|

  • 求解 n 阶矩阵

    Sn是序列{1,2,,n}(即列编号)的全部置换的合集设 S_n 是序列 \set{1,2,\dots,n}(即列编号)的全部置换的合集(相关知识见“组合与排列”)

    A=σSnsgn(σ)i=1nai,σ(i)|A| = \sum_{\sigma \in S_n} sgn(\sigma) \prod_{i=1}^{n} a_{i,\sigma(i)}

    或者利用代数余子式计算(只验证过 3 阶矩阵可用):

    A=j=0na1,jC1,j|A|= \sum_{j=0}^n a_{1,j}|C_{1,j}|

  • 求解 2 阶矩阵

    a1,1a1,2a2,1a2,2=a1,1a2,2a1,2a2,1\begin{vmatrix} a_{1,1} & a_{1,2} \\ a_{2,1} & a_{2,2} \\ \end{vmatrix} = a_{1,1} a_{2,2} - a_{1,2} a_{2,1}

TRS 矩阵的表示

TRS 矩阵是最常用的变换矩阵,其本质就是平移、旋转、缩放矩阵的复合,其复合顺序为:

平移矩阵旋转矩阵缩放矩阵平移矩阵 * 旋转矩阵 * 缩放矩阵

平移矩阵(Translate)

[100x010y001z0001] \begin{bmatrix} 1&0&0&x\\ 0&1&0&y\\ 0&0&1&z\\ 0&0&0&1 \end{bmatrix}

旋转矩阵(Rotate)

Z轴旋转矩阵=[cos(z)sin(z)0sin(z)cos(z)0001] Z轴旋转矩阵= \begin{bmatrix} \cos(z)&-\sin(z)&0\\ \sin(z)&\cos(z)&0\\ 0&0&1 \end{bmatrix}

X轴旋转矩阵=[1000cos(x)sin(x)0sin(x)cos(x)] X轴旋转矩阵= \begin{bmatrix} 1&0&0&\\ 0&\cos(x)&-\sin(x)&\\ 0&\sin(x)&\cos(x) \end{bmatrix}

Y轴旋转矩阵=[cos(y)0sin(y)010sin(y)0cos(y)] Y轴旋转矩阵= \begin{bmatrix} \cos(y)&0&\sin(y)&\\ 0&1&0&\\ -\sin(y)&0&\cos(y) \end{bmatrix}

若旋转矩阵要同时表示 3 轴旋转,就是通过对 x、y、z 旋转矩阵的复合得出的,如 Unity 中的复合顺序为:

Z轴旋转矩阵X轴旋转矩阵Y轴旋转矩阵Z轴旋转矩阵 * X轴旋转矩阵 * Y轴旋转矩阵

推导复合顺序过程是这样的:

  1. 在 Unity 中放一个方块。
  2. 对其先后进行 x、y 旋转并逆序尝试。
  3. 发现 Y 旋转永远都是以世界 Y 轴为准而不受物体 Y 轴的影响。
  4. 说明 X 旋转无法干扰 Y 旋转,但反之可以。
  5. 故矩阵复合一定是先 Y 后 X,Z 同理推出。

缩放矩阵(Scale)

[x000y000z] \begin{bmatrix} x&0&0\\ 0&y&0\\ 0&0&z \end{bmatrix}

TRS 矩阵的拆解

从 TRS 矩阵中逆推出原本的位移、旋转、缩放。

部分情况下旋转是无法被真正逆推回来的,这也解释了为什么旋转到特定角度时继续旋转会出问题,因此旋转物体时要保留原始的旋转值,不能完全依靠矩阵。

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
Vector3 position;
Vector3 rotation;
Vector3 scale;
Matrix4x4 matrix4X4 = transform.localToWorldMatrix;
position = matrix4X4.GetColumn(3);
Matrix4x4 sqrScaleMatrix = matrix4X4.transpose * matrix4X4;
scale = new Vector3(Mathf.Sqrt(sqrScaleMatrix.m00), Mathf.Sqrt(sqrScaleMatrix.m11), Mathf.Sqrt(sqrScaleMatrix.m22));
Matrix4x4 rotationMatrix = matrix4X4 * Matrix4x4.Scale(new Vector3(1 / scale.x, 1 / scale.y, 1 / scale.z));
if (Mathf.Abs(Mathf.Abs(rotationMatrix.m12) - 1) > 0.001f) //A(Sinx) != 1,CosX != 0
{
//cosX为负?
rotation.y = Mathf.Atan2(rotationMatrix.m02, rotationMatrix.m22);
rotation.z = Mathf.Atan2(rotationMatrix.m10, rotationMatrix.m11);
float cosX = rotationMatrix.m02 != 0
? rotationMatrix.m02 / Mathf.Sin(rotation.y)
: rotationMatrix.m22 / Mathf.Cos(rotation.y);
rotation.x = cosX > 0
? Mathf.Asin(-rotationMatrix.m12)
: Mathf.PI - Mathf.Asin(-rotationMatrix.m12);
}
else //Abs(Sinx) == 1,CosX == 0
{
if (-rotationMatrix.m12 > 0)
{
float yMinusZ = Mathf.Atan2(rotationMatrix.m01,rotationMatrix.m00);
rotation.z = 0;
rotation.y = yMinusZ;
rotation.x = Mathf.PI / 2;
}
else
{
float yAddZ = Mathf.Atan2(-rotationMatrix.m01,rotationMatrix.m00);
rotation.z = 0;
rotation.y = yAddZ;
rotation.x = -Mathf.PI / 2;
}
}
rotation *= Mathf.Rad2Deg;

【数学】矩阵
https://bdffzi-blog.pages.dev/posts/3073109274.html
作者
BDFFZI
发布于
2024年10月10日
许可协议