当前位置: 首页 > 科技观察

矩阵乘法与CSS3d变换(transform)

时间:2023-03-21 19:06:13 科技观察

小科普:关于矩阵乘法,以两个二阶齐次矩阵相乘为例[[a11,a12,*b11,b12,=a11*b11+a12*b21,a11*b12+a12*b22,a21,a22b21,b22a21*b11+a22*b21,a21*b12+a22*b22]]]由此可见,两个矩阵相乘就是取每一行第一个乘以第二个的每一列,所以两个矩阵相乘也有一个规则,即第一个矩阵的列数(每行元素数)必须与第二个矩阵的行数进行比较matrix乘法运算只有在数字(每列中的元素数)相等时才会发生。先回答第一个问题:window.getComputedStyle(htmlElement)['transform']查询出来的值表示一个matrix3d函数的一个参数,比如matrix3d(a1,b1,c1,d1,a2,b2,c2,d2,a3,b3,c3,d3,a4,b4,c4,d4)其中a1b1c1d1a2b2c2d2a3b3c3d3表示线性变换,a4b4c4d4表示位移变换。如果空间中点的表示是列向量表示,那么它的矩阵形式应该是这样的:a1a2a3a4b1b2b3b4c1c2c3c4d1d2d3d4在下面的例子中我们都假设在空间点表示为列向量。使用右手坐标系。(其实这里也可以写成矩阵的转置形式,下面进行乘法运算时,分别进行转置,然后也可以交换两个矩阵的位置,结果就是3d变换的初始矩阵如下:1000010000100001这是一个单位矩阵,这样的矩阵满足矩阵乘法的交换律,与1在整数中,乘以任意数或任意数,所以单位矩阵与其他矩阵相乘没有影响。translatetranslate表示位移变换,3dtranslate变换矩阵对应一个4阶齐次矩阵T如下:100dx010dy001dz0001假设点D在坐标形状space例如:xyz1对他应用一个平移矩阵后,结果可以是T*D:1*x+0*y+0*z+dx,x+dx0*x+1*y+0*z+dy,=y+dy0*x+0*y+1*z+dz,z+dz0+0+0+1,上面1的变换写成matrix3d函数:matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,dx,dy,dz,1)等价于:translate3d(x,y,z)。变换矩阵的前三行可以看作是对空间坐标系中的某一点进行某种变换的x、y、z轴上的表示,每一行的前三列分别代表x、y和z轴。需要具体的变换,比如位移变换矩阵的第一行表示x轴上的点要做的变换,那么对应的y和z的值为0。(这个有点个人想法,可以略过。。。)scalescale表示一个缩放变换,缩放的具体值体现在主对角线上,比如一个1.5倍的缩放矩阵S:1.500001.500001.500001为上点D应用缩放矩阵得到S*D:1.5*x+0*y+0*z+0*11.5x0*x+1.5*y+0*z+0*1=1.5y0*x+0*y+1.5*z+0*11.5z0*x+0*y+0*z+1*11等同于:matrix3d(1.5,0,0,0,0,1.5,0,0,0,0,1.5,0,0,0,0,1)可以简写为:scale3d(1.5,1.5,1.5)rotaterotate表示二维平面的旋转二维平面的旋转表示一个点围绕一个点旋转时,一个二维变换可以用一个三阶齐次矩阵来表示。矩阵的推导可以推导如下:首先,主对角线上的缩放值,第三列的位移值为默认值1(表示原始大小)和0(表示原始位置):100010001我们以下面的二维坐标系为例:将两个单位向量在x轴和y轴上旋转一个角度θ,得到的A'就是x轴上的旋转矩阵的值轴,得到的B'是y轴上旋转矩阵的值,所以2d旋转矩阵是这样的(图片上的坐标系用行向量表示,为了统一我们进行atransposition):cos0-sin0sin0cos03d空间的旋转在3d空间中,旋转不再是绕某个点的旋转,而是绕某个轴(x,y,z轴)的旋转。以绕x轴旋转为例(这张图有点不一样,其实BB'应该平行于y轴,AA'应该平行于Z轴,很好理解。有是没办法画的技巧太差了--,绕某个轴旋转就是想像这个轴不动然后另一个垂直于他的轴绕它旋转):所以绕x轴的旋转矩阵可以是写成如下:10000cos0-sin000sin0cos000001我们可以写一个rotateX(60deg),那么对应的matrix3d的参数就是:matrix3d(1,0,0,0,0,0.5,0.866025,0,0,-0.866025,0.5,0,0,0,0,1)同理可以得到绕z轴和y轴的旋转矩阵:Z:cos0-sin000sin0cos00000100001Y:cos00sin000100-sin00cos000001至此css中的3D变换基本完成,接下来可以将上面的矩阵乘以不同的组合得到复合变换。值得注意的是矩阵乘法一般不满足交换律,所以运算顺序还是比较重要的。那为什么图形变换在计算机中普遍采用矩阵表示呢?根据我现在看到的资料,还是很方便的。使用矩阵运算后,可以将多次变换统一为矩阵乘法运算,便于计算机流水线处理。最后回答第二个问题:为什么硬件加速要用transform,为什么硬件加速更快?第一点是因为css的3dtransform属性用在一个元素上,元素会被提升到一个单独的层,在一个单独的层上使用一些transformation可以直接跳过浏览器渲染、布局和绘制的一般过程,计算完成后直接进行合成。这是第一点快,第二点是因为transform变换后的元素的操作是发生在gpu上的,gpu本身的多核在处理并发操作的时候比cpu快。最后分享一个矩阵乘法运算,可以验证css变换相关的矩阵运算//矩阵乘法函数multipy(a,b){letr=a.length;让col=a[0].length;让结果=[];for(leti=0;i