1. 矩阵数学概念
大家上次听到矩阵这个词是什么时候?应该是大学时候的线性代数。线性代数是大多数人的噩梦,概念可能已经忘得差不多,先来回顾一下
- 在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合, 最早来自于方程组的系数及常数所构成 的方阵
- 由 m × n 个数排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵。
2. 矩阵和向量
- 向量可以用矩阵表示,且有时特殊矩阵就是向量
- 矩阵包含向量
- 向量的运算离不开矩阵
3. 矩阵乘法
矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和。线性代数是向量计算的基础,很多重要的数学模型都要用到向量计算
4. CSS中的matrix
- transform属性大家应该很熟悉,实际上transform的几个值translate、scale、skew、rotate最终底层都会转换为matrix矩阵来进行计算。
- 上面的公式表示坐标x,y经过矩阵变换matrix(a,b,c,d,e,f)后,得到新的坐标x’,y’
5. 浏览器坐标系
先来简单了解一下浏览器坐标系。
- 浏览器朝右为x轴方向
- 浏览器朝下为y轴方向
- 浏览器朝外为z轴方向
6. matrix实现translate、scale、skew、rotate
我们先来实现2维坐标系的transform。
在线体验:https://demo.wilberjiang.com/matrix/
7. 平移
-
定义:平移,是指在同一平面内,将一个图形上的所有点都按照某个直线方向做相同距离的移动,这样的图形运动叫做图形的平移运动,简称平移。平移不改变图形的形状和大小。图形经过平移,对应线段相等,对应角相等,对应点所连的线段相等。 它是等距同构,是仿射空间中仿射变换的一种。它可以视为将同一个向量加到每点上,或将坐标系统的中心移动所得的结果
-
由此我们可以得出( x , y )经过平移后为( x + e , y + f )
-
再由上面的公式得出 x + e = ax + cy + e 和 y + f = bx + dy + f
-
所以平移矩阵为:
8. 缩放
- 定义:缩小或放大,在欧几里德几何中,均匀缩放是放大或缩小物体的线性变换;缩放因子在所有方向上都是一样的;它也叫做位似变换。均匀缩放的结果相似(在几何意义上)于原始的物体。
- 由此我们可以得出( x , y )经过缩放后为( ax , dy )
- 再由上面的公式得出 ax = ax + cy + e 和 dy = bx + dy + f
- 所以缩放矩阵为:
9. 拉伸
- 定义:这种转换是一种剪切映射(横切),它在水平和垂直方向上将单元内的每个点扭曲一定的角度。每个点的坐标根据指定的角度以及到原点的距离,进行成比例的值调整;因此,一个点离原点越远,其增加的值就越大。
- 由此我们可以得出( x , y )经过拉伸后为( x + cy , bx + y )
- 再由上面的公式得出 x + cy = ax + cy + e 和 bx + y = bx + dy + f
- 所以拉伸矩阵为:
10. 旋转
- 定义:在平面内,一个图形绕着一个定点旋转一定的角度得到另一个图形的变化叫做旋转。这个定点叫做旋转中心,旋转的角度叫做旋转角,如果一个图形上的点A经过旋转变为点A’,那么这两个点叫做旋转的对应点
- 由此我们可以得出( x , y )经过旋转后为( cosθ * x – sinθ * y, sinθ * x + cosθ * y )
- 再由上面的公式得出 cosθ * x – sinθ * y = ax + cy + e 和 sinθ * x + cosθ * y = bx + dy + f
- 所以旋转矩阵为:
11. 组合
12. 3D矩阵变换
13. 矩阵应用场景
- SVG transform=“matrix(a b c d e f)”
- Canvas context.transform(2,0,0,2,150,150);
- WebGL 矩阵在3D渲染中不可缺少,坐标变换有模型变换,视图变换,投影变换等多种。
- CSS 3D transform: matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)
14. 思考:不使用matrix能否实现镜像翻转
写在最后
你可以开发你的想象用它来写一个动画库,像这样:
@keyframe animation{
20%{
transform: matrix(1,0,0,1,20,-20);
}
45%{
transform: matrix(1,0,0,1,45,-34.4);
}
70%{
transform: matrix(1,0,0,1,15,-14.4);
}
85%{
transform: matrix(1,0,0,1,5,-4.4);
}
…
}
@keyframe animation{ 20%{ transform: matrix(1,0,0,1,20,-20); } 45%{ transform: matrix(1,0,0,1,45,-34.4); } 70%{ transform: matrix(1,0,0,1,15,-14.4); } 85%{ transform: matrix(1,0,0,1,5,-4.4); } … }
@keyframe animation{
20%{
transform: matrix(1,0,0,1,20,-20);
}
45%{
transform: matrix(1,0,0,1,45,-34.4);
}
70%{
transform: matrix(1,0,0,1,15,-14.4);
}
85%{
transform: matrix(1,0,0,1,5,-4.4);
}
...
}
甚至来画一个3D模型,像这样: