来人!把朕的线性代数呈上来!
为啥讲数学?
先说下一个时间线:- 无意间发现了一个宝藏up主3Blue1Brown[1]
- 在看视频的时候,偶然发现一个集合:线性代数的本质。突然想起上学的时候矩阵论(线性代数)老师总说矩阵很优美,但我又一直没get到,所以好奇想看一看。
- 看了一部分觉得很有意思,于是想分享下~
- 但是有没有啥用呢?在评论里看到矩阵是图形学的基础,于是搜了下,发现它比我想的有用多了!只要涉及到图形学,矩阵都是绕不开的,比如webgl等等;
- 但是和我们前端的大部分日常工作关系不大,讲了大家会有兴趣吗?纯讲理论能讲的明白不?于是我突然想到transform里用到了矩阵,是一个合适的实践例子
- 至此,我发现矩阵既有意思,又有意义,又可以有实践例子(transform),于是有了这篇文章。
讲什么?
几乎所有的学科(理工科)都要学线性代数,比如计算机科学、物理学、电子工程学、机械工程学、统计学等等。我们学习了如何计算矩阵:数乘、叉乘、特征值等,但是也只限于计算,大家会不会有以下几个疑问:- 这里计算的规则为什么是这么定义的?
- 我们为什么要学这些?
- 学这些有什么实际用处?
- 一部分:内容来自于宝藏up主的线性代数合集[2],主要是讲一些基本矩阵运算的几何含义,我按我的理解分享下,更多精彩推荐大家去看原视频。
- 二部分:通过transform的矩阵,来消化所讲的内容。
向量及基本运算
矩阵的基础是向量,我们先来看看向量。向量在不同学科眼里是不同的东西,甚至于它可以是任何东西,只要保证其相加和数乘有意义即可。为什么只需要相加和数乘,一会下面会说明:只需要这2种运算,就可以到达空间内的任何一点。相加
- 数学表示+ = ,+= 。
- 几何表示:
数乘
- 数学表示:==
- 几何表示:
线性组合、张成空间与基
在描述向量时,有一个我们用到了但是没注意的东西:向量的基。我们都是默认了向量的基坐标为平面坐标系上x轴方向上的和y方向上的。矩阵和线性变换
以上向量是基础运算,一切都是为了更好的理解矩阵运算。很遗憾,矩阵是什么是说不清的,你必须得自己看看。——墨菲斯 函数是将一个输入经过一些处理变为一个输出,如y=f(x)。那向量的运算a=L(b)也是如此,为什么我们不把向量的运算叫函数,而都是叫向量变换/矩阵变换呢。这提醒我们要用运动的思想看待向量的计算,或者换一种说法,矩阵/向量变换是对空间的变换。说明一点,比函数稍微简单的是,矩阵变化都是线性变换(因为都是依赖向量数乘和相加)。- 原点不动
- 直线依然是直线
矩阵向量相乘
理解一个【矩阵是一次对空间的变换,且其中2列分别为经过变换后的基向量和】这一点至关重要,这是理解所有后续操作的基础。现在,我们回答上面的问题:如果你想知道一个向量,比如,经过线性变化后的位置,也就是L()的位置,则只需要计算+=+即可。矩阵乘法
矩阵是对一个空间的变换,那如果我们想相继对空间进行多次变换呢?此时,我们就不一步步描述一个具体的向量的去向,直接描述整个平面的变换,更具体的过程大家可以去看看视频。我们先对平面进行一个 = 变换:变换至,变换至,然后进行一个=变换。此时将变换为== =+ =此时将变换为= = = + =乘法结合律和交换律
如果大家还有点印象的话,矩阵是满足乘法结合律,而不满足乘法交换律的。为什么是这样呢?通过几何意义,我们可以很好地理解原因。- 结合律:?=
- 交换律:?=
矩阵的运算顺序是从右往左,可能不太符合常规习惯。不过想一想前面提到的,矩阵运算其实就是对空间进行函数运算,再结合复合f(g(x))的写法:先计算g(x),再计算f(g(x)),就不难理解了。
行列式
其实讲到的东西已经足以说明了矩阵的几何意义,后续提到的transform也只需要以上理解就可以了,不过我还是想继续抽一个其他概念简述一下,以说明矩阵的其他各种概念也都有着其相对应的实际(几何)意义。如果大家还有印象,行列式的计算规则为 = ad-bc,这一值代表着什么呢?我们一步步来看一下。- 先假设c和b均为0,那这样矩阵对应的空间变换为:变为,变为,则此时= =ad,看起来是表示空间上一个单位面积被缩放的倍数。

- 再恢复b不为0,这样变为,变为,从平面上来看变为了一个平行四边形,计算= =ad,正好也等于平行四边形面积,依然是ad,

- 接着我们再恢复c部位0,此时变为,变为,变换如下图,停下来计算一下:=(a+b)(c+d)-ac-bd-2bc=ad-bc,正好是基向量变换后围成的面积。
基本格式
transform: matrix(a,b,c,d,e,f)
其对应的矩阵为A = ,假设平面上的一点为(x,y),则经过变换后为=。再次回顾下,这里A为对平面(坐标系)的变换,其中(a,b)是变换后的基向量,(c,d)是变换后的基向量。基于上面的理解,我们知道一个平面的变换,用22的矩阵就可以,也就是,为啥会多出e和f形成了33的矩阵,这个和translate有关,因此我们先来看下translate。以下场景的demo[4]translate
translate属性表示为元素的位移,也就是不涉及到对坐标系的变换,因此改变参数中的a、b、c、d是没法做到的,我们需要增加一个单纯的位移维度,也就是对(x,y)平移(e,f)后坐标要变为(x+e,y+f),且同时我们要保持的功能不变(假设我们已经知道其作用,后面再讲)。因此保持和不变,我们可以得到=,也就得到了变换后的点(x+e,y+f)。加上对平面的变换后,我们就可以得到以上的通用变换矩阵了。
小结:translate仅需用到参数e和f,translate(e,f)对应matrix(1,0,0,1,e,f)。scale
scale属性表示对元素的缩放,也就是坐标系缩放了,但是不会变形;即只进行矩阵的数乘变换,变为,变为,其中m和n为标量。对应到矩阵上,即变换为,也就是。小结:scale仅需用到参数a和d,scale(a, b)对应matrix(a,0,0,d,0,0)。rotate
rotate属性表示对元素的旋转,这里就涉及到三角函数。旋转后,变为,变为,。对应到矩阵上,即变换为。组合使用
transform的其他属性就不一一说明了,我们来看看这些属性如何组合使用。先问个问题:如果我们想要将元素缩小为0.5倍,且右移50px,会怎么写?.element{
transform: translate(50px, 0) scale(0.5);
}
.element{
transform: scale(0.5) translate(50px, 0);
}
以上2种写法有区别吗?上面我们提到,每次矩阵左乘是一次变换,多次变换就多次左乘即可。假设Translate的矩阵为,Scale的矩阵为,元素上的点矩阵为。- :先,后,对应写法transform: translate(50px, 0) scale(0.5); ,表示对元素先Translate,后Scale。
- :先,后,对应写法transform: scale(0.5) translate(50px, 0);, 表示对元素先Scale,后Translate。
- 先使用scale缩小到0.5倍之后,后续的translate的50px也缩小为了0.5倍,即50*0.5=25px;
- 先使用translate,对于平面没有影响,因此对后续的scale没有影响
- transform: translate(100%, 0) translate(50px, 0);,先右移100%,再右移50px
- transform: scale(2) scale(3);先放大2倍,再基于此放大3倍,共2*3=6倍,而不是2+3=5倍。
- m < n, 3*3代表什么?
- m > n, 2*2代表什么?
3Blue1Brown: https://space.bilibili.com/88461692/
[2]宝藏up主的线性代数合集: https://www.bilibili.com/video/BV1ys411472E
[3]验证demo: https://codepen.io/yh418807968/pen/bGgVvRM?editors=1111
[4]demo: https://codepen.io/yh418807968/pen/Vwmdvaw
[5]demo: https://codepen.io/yh418807968/pen/Vwmdvaw

评论