CSS3——CSS3矩阵matrix进行2D变换的数学原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Tracy_frog/article/details/82936824

css3的2D转换中matrix接受6个参数,却可以实现平移、旋转、放缩、斜切四种效果。它是如何做到的呢?

此处的你有两个选择
0 - 对自己有较高要求!老老实实静下心来将本文看完,
1 - 直接看总结——点我直达,只学习如何使用matrix

预备知识:矩阵相乘、三角函数,fighting!

此处附上矩阵相乘的百度百科定义
在这里插入图片描述
我们先将matrix接受的六个参数记为a,b,c,d,e,f,则该变换矩阵记为
在这里插入图片描述
二维平面上一个点记为(x,y),为了与向量区分开,我们使用数字1代表点,0代表向量,则二维平面上一个点应记为(x,y,1),为了使该点经过变换后依旧为(x,y,1)的形式,矩阵可以改为
在这里插入图片描述
进行相乘变换(自行百度矩阵相乘的公式)
在这里插入图片描述
我们得到了一个新的点(ax+cy+e,bx+dy+f,1)
怎么将这个冷冰冰的点和我们的平移旋转缩放斜切联系到一起呢?

平移

我们知道,对一个点(x,y,1)向x轴正向平移10,向y轴正向平移20,得到的点为(x+10,y+20,1),而经过矩阵变换的点为(ax+cy+e,bx+dy+f,1),对比得到a=1,c=0,e=10,b=0,d=1,f=20
所以变换矩阵为
在这里插入图片描述

transform: matrix(1,0,0,1,10,20); // a=1,c=0,e=10,b=0,d=1,f=20

显然,与平移变换直接相关的参数为e、f参数!!
当我们只进行平移变换时,只需要这样

transform: matrix(1,0,0,1,e,f); // 相当于 transform: translate(e,f);

放缩

假设我们对一个边长为10px的正方形放大2倍,如图所示
在这里插入图片描述
对左上角的那个点来说,它由(0,10,1)变为(0,20,1)
对任意一个点(x,y,1)来说,放大后得到的点为(2x,2y,1),而经过矩阵变换的点为(ax+cy+e,bx+dy+f,1),对比得到a=2,c=0,e=0,b=0,d=2,f=0
所以变换矩阵为
在这里插入图片描述

transform: matrix(2,0,0,2,0,0); // a=2,c=0,e=0,b=0,d=2,f=0

显然,与缩放变换直接相关的参数为a、d参数!!
当我们只进行平移变换时,只需要这样

transform: matrix(a,0,0,d,0,0); // 相当于 transform: scale(a,d)

聪明的你现在肯定猜到了,如果既进行平移,又进行缩放,则transform: matrix(a,0,0,d,e,f);即可,a、d表示缩放,e、f表示平移

旋转

剩下两个参数b、c,可是还有旋转和斜切没有实现呢!(冒汗
旋转的话,涉及到旋转角度的问题啦。记为θ。
复习一波三角函数,以下使用极坐标表示
在这里插入图片描述
来一波推理
在这里插入图片描述
对任意一个点(x,y,1)来说,旋转θ°后得到的点为(xcosθ-ysinθ,xsinθ+ycosθ,1),而经过矩阵变换的点为(ax+cy+e,bx+dy+f,1),对比得到a=cosθ,b=sinθ,c=-sinθ,d=cosθ,e=0,f=0
所以变换矩阵为
在这里插入图片描述
这里用到了a、b、c、d四个参数,前面我们知道缩放用了a、d两个参数,如果我们既要旋转又要缩放怎么办呢??

已经证明:任何二维组合变换均可分解为多个基本变换的乘积

故我们只需要分别求出变换矩阵,再相乘即可。

q=DCBAp => q=(DCBA)p=Mp

解释:p表示当前的点,ABCD表示四种变换,上述式子的变换顺序为A->B->C->D

斜切

先沿x轴扭曲
在这里插入图片描述
有以下式子
在这里插入图片描述
与(ax+cy+e,bx+dy+f,1)对比得出a=1,c=tanθ,e=0,b=0,d=1,f=0
所以变换矩阵为
在这里插入图片描述
再看沿y轴扭曲
在这里插入图片描述
在这里插入图片描述
变换矩阵为
在这里插入图片描述
当l种变换同时进行时,有
在这里插入图片描述
【思考】我们之前说过,任何二维组合变换均可分解为多个基本变换的乘积,为什么这里不是将两个扭曲矩阵相乘呢?(先沿x轴扭曲,再沿y轴扭曲?
emmm,是这样的,我们这里的计算都是相对最初始的图形,如果用两个矩阵相乘,则是使初始图形沿x轴扭曲θx度后得到的新图形再对y轴扭曲θy度!!如果要达到我们想要的效果,就只能重新计算沿y轴的扭曲角度!!

总结
至此我们已经把2D变换的数学原理挖出来了,写一个用法总结,便于自己查找也便于大家查看

  • 平移,只需要控制最后两个参数e、f,a、d参数为1
transform: matrix(1,0,0,1,e,f);
// 等同于
transform: translate(e,f);
  • 放缩,只需要控制a、d参数,其它为0
transform: matrix(a,0,0,d,0,0); 
// 等同于
transform: scale(a,d);
  • 旋转,只需要控制a、b、c、d参数
transform: matrix(cosθ, sinθ, -sinθ, cosθ);
// 等同于
rtransform: rotate(θdeg)
  • 斜切
transform: matrix(1, tanθy, tanθx, 1, 0, 0);
// 等同于
transform: skew(θx, θy);
  • 复合变换
    如以下这种类型,先旋转再缩放再扭曲,如何用矩阵得到呢?
transform: rotate(360deg) scale(2,2) skew(10deg,5deg);

已经证明:任何二维组合变换均可分解为多个基本变换的乘积
故我们先求出旋转矩阵A,缩放矩阵B和斜切矩阵C
最后得到变换矩阵M = CBA = C(B(A))

【什么时候我们用矩阵?】
思考下,既然已经有rotate、scale等函数,直接调用不就行了吗??为什么人类要跟自己过不去,手算矩阵???
大部分情况下,当然是使用那些基本的rotate、scale函数就好了,下面这种类型的情况呢?

  • 需求说:请把这些点沿着y轴取对称。 你:简单
    x’ = ax+cy+e = -x,y’ = bx+dy+f = y嘛,一番心算后你得到
    transform: matrix(-1,0,0,1,0,0);
    
  • 需求说:算了,还是对y=x取对称吧。你:简单,先整体旋转逆时针旋转45°,再对y轴取对称,再整体顺时针旋转45°(45°)就好了嘛~
    在这里插入图片描述
    (上图右侧表示逆时针旋转)
    transform: matrix(0,1,1,0,0,0);
    
    用我们的高中数学来验证一波,点(a,b)关于y=x轴取对称,得到的点应该为(b,a)
    在这里插入图片描述
    验证正确!
  • 需求犹豫了0.5s,哎呀还是对y=kx取对称吧…
  • 需求摇摇头说,对y=kx+b取对称吧…

此处插播高中知识——如何关于一条直线取对称点呢?

  1. 两个点关于一条直线对称,那么这两个点的连线的中点必在该直线上
  2. 两个点的连线所在直线的斜率与该直线斜率的乘积为-1(因为垂直)
  3. 可以列出两个方程,求出对称点!
  4. 对称点都求出来了,矩阵也就出来了~
  • 现在请看官使用rotate、scale、skew、translate实现上述需求~

【demo】使用css3画一个立方体

【参考】
https://www.atjiang.com/css-transform-skew-angle/
http://0313.name/archives/66
https://www.zhangxinxu.com/wordpress/2012/06/css3-transform-matrix-矩阵/
http://www.wukai.me/2015/10/22/css3-cube/

展开阅读全文

没有更多推荐了,返回首页