几何意义
SVG 是一种矢量图形,放大可以不失真。
线性代数的 数值操作 和 几何直观
几何直观:更容易在不同场景中引入概念来解决问题。如:sinA
向量可以是任何东西,只要保证向量相加和数字和向量相乘有意义即可。 向量相加和向量数乘贯彻向量的始终。 向量是一个箭头(有方向,有距离),一个点,二维平面是一个坐标。
数乘就是向量的缩放,2*[2,3]
i 是 x 轴的基向量 j 是 y 轴的基向量 坐标【2,-3】是标量,将基向量拉长。[2,-3]相当于经过缩放的向量的和,2i+(-3)j




简单理解:某个点的位置为(2,3)。开始时在i(1,0)方向走两步,在j(0,1)方向走3 步。后来逆时针旋转 90 度,变成在 i 上走(0,1)上走 2 步,在 j(-1,,0)上走3 步。 matrix(0, -1, 1, 0, 0, 0); 是传递的基向量的坐标。
线性变换是指定变换后的基向量的坐标,然后根据坐标进行对应的数乘运算。 一个矩阵就是对空间的一种线性变换。
连续变换是矩阵相乘
矩阵应用
javascript
transform: translate(10px, 10px); => transform: matrix(1, 0, 0, 1, 10, 10);
transform: scale(1, 0.5); => transform: matrix(1, 0, 0, 0.5, 0, 0);
transform: rotate(45deg); => matrix(cos45,sin45,-sin45,cos45,0,0) => transform: matrix(0.866025,0.500000,-0.500000,0.866025,0,0);
transform: skew(30deg, 30deg); => matrix(1,tan(θy),tan(θx),1,0,0)
=> transform: matrix(1, 0.57735, 0.57735, 1, 0, 0);
变换类型 | 变换方法 | matrix 写法 |
---|---|---|
平移 | translate(translateX, translateY) | matrix(1, 0, 0, 1, translateX, translateY) |
缩放 | scale(scaleX, scaleY) | matrix(scaleX, 0, 0, scaleY, 0, 0) |
斜拉 | skew(angleX, angleY) | matrix(1, tan(angleY), tan(angleX), 1, 0, 0) |
旋转 | rotate(angle) | matrix(cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0) |
matrix(scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY()) 旋转,拉伸,平移变换,本质上都是通过 Matrix() 方法实现的。CSS 提供 Transform:rotate这种方式是一种语法糖。方便写更容易维护的代码,并且操作简单。
线性变换
线性变换两个要求:直线依然是直线,原点保持固定不变。意思是:保持网格线平行且等距分布。缩放,旋转可以实现。也就是 a,b,c,d四个参数。但是平移需要移动坐标原点,所以引入了 e,f两个参数分别是坐标原点的变化。
仿射变换 = 线性变换 + 平移变换 仿射变换矩阵中:
基向量的变化:
**坐标原点的变化: **
平移计算
CSS3 transform matrix矩阵偏移分解实例页面
css
#mydiv{ transform: matrix(1, 0, 0, 1, 150, 150); }
相当于transform: translate(150px,150px)。点(220px,220px)的坐标 齐次坐标能区分是一个向量还是一个点 从普通坐标转换成齐次坐标时 如果(x,y,z)是个点,则变为(x,y,z,1); 如果(x,y,z)是个向量,则变为(x,y,z,0) 反之成立
使用场景
- 当使用 transform 不满足需求,没有提供对应的接口,需要使用更复杂的变换操作,可以使用 matrix。如:镜像对称效果。
- 当位移,变换操作较多,计算较复杂时,使用 tansform 不方便,可以新建一个 6 个参数的数组,所有操作计算结束后,将数组作为参数传递给 Matrix()。 【连续变换:矩阵相乘】
镜像对称
任意对称轴都可以用y = k * x表示。则matrix表示就是:
scss
matrix((1 - k * k) / (1 + k * k), 2k / (1 + k * k), 2k / (1 + k * k), (k * k - 1) / (1 + k * k), 0, 0)
通过 2 个方程
- 垂直的两条线斜率相乘等于-1 :(y - y') / (x - x') = -1 / k → ky - ky' = -x + x'
- 因为镜像,所以中点在轴线上: (x + x') / 2 * k = (y + y') / 2 → kx + kx' = y + y'
把x'和y'提出来: x' = (1 - k * k) / (k* k + 1) * x + 2k / (k * k + 1) * y y' = 2k / (k * k + 1) * x + (k * k - 1) / (k * k + 1) * y
结合矩阵公式: x' = ax + cy + e y' = bx + dy + f
对应项系数相等: a = (1 - k * k)/(k * k + 1) b = 2k / (k * k + 1) c = 2k / (k * k + 1) d = (k * k - 1)/(k * k + 1)
只需要知道对称轴的斜率 k ,就可以算出来matrix 中 a,b,c,d的值,如果对称轴不经过坐标轴原点,使用 e,f 进行平移。 踩了两个坑:
- 斜率的计算需要是y的变化量/x的变化量、符号不要搞错了:(y - y') / (x - x') 或者 (y'- y) / (x' - x)
- 数学中的y=x在web开发中需要注意y轴是向下的,和数学中的y轴相反
复合变换
复合变换是连续进行多个变换。 比如:放大 1.5 倍并旋转 45°。 transform: rotate(45deg) scale(1.5); 旋转矩阵表示为向量,[cos(a) sin(a) -sin(a) cos(a) 0 0]其中_a_是角度。为了缩放,我们需要使用矩阵[sx 0 0 sy 0 0] transform: matrix(1.0606, 1.0606, -1.0606, 1.0606, 0, 1)
常用参数参考
参考
Understanding the CSS Transforms Matrix 理解CSS3 transform中的Matrix(矩阵) 仿射变换及其变换矩阵的理解 线性映射的矩阵的例子