自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

矩陣的乘法運(yùn)算與CSS的3d變換(transform)

開(kāi)發(fā) 前端
你有沒(méi)好奇過(guò),在一個(gè)使用了transform變換的元素上使用window.getComputedStyle(htmlElement)[‘transform’] 查詢出來(lái)的值代表什么?為什么硬件加速要使用transform,以及為什么硬件加速會(huì)快?

小科普:關(guān)于矩陣的乘法

以兩個(gè)二階齊次矩陣相乘為例
[ [ [
a11,a12, * b11,b12, = a11*b11 + a12* b21 , a11*b12 + a12*b22,
a21,a22 b21,b22 a21*b11 + a22* b21 , a21*b12 + a22*b22
] ] ]

由此,可以看到兩個(gè)矩陣相乘就是拿第一個(gè)的每一行,乘以第二個(gè)的每一列,因此兩個(gè)矩陣相乘也有個(gè)規(guī)定就是第一個(gè)矩陣的列數(shù)(每一行元素的個(gè)數(shù)),要與第二個(gè)矩陣的行數(shù)(每一列元素的個(gè)數(shù))相等才可以發(fā)生乘法運(yùn)算。

首先回答第一個(gè)問(wèn)題: 由window.getComputedStyle(htmlElement)[‘transform’]查詢出來(lái)的值代表一個(gè)matrix3d函數(shù)的參數(shù),形如matrix3d(a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, a4, b4, c4, d4)

其中a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3,代表了線性變換,a4 b4 c4 d4代表的是位移變換。若空間中點(diǎn)的表示是一個(gè)列向量表示,那么,他的矩陣形式應(yīng)該是這樣的:

a1 a2 a3 a4
b1 b2 b3 b4
c1 c2 c3 c4
d1 d2 d3 d4

在下邊的例子中我們都假定空間中的點(diǎn)是以列向量形式表示的。使用右手坐標(biāo)系。

(實(shí)際這里也可以寫(xiě)成該矩陣的轉(zhuǎn)置形式,在下邊進(jìn)行乘法運(yùn)算時(shí)都分別轉(zhuǎn)置下,然后交換兩個(gè)矩陣的位置也是可以的,結(jié)果是一樣的)

3d變換的初始矩陣如下:

1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

這是一個(gè)單位矩陣,這樣的矩陣滿足矩陣乘法運(yùn)算的交換律,且和整數(shù)中1的作用一樣,乘以任何數(shù)還是任何數(shù),因此單位矩陣與其他矩陣的乘法運(yùn)算不產(chǎn)生任何效果。

translate

translate代表一個(gè)位移變換,3d的translate變換矩陣對(duì)應(yīng)的是一個(gè)如下的4階齊次矩陣 T :

1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0 1

假設(shè)空間內(nèi)某個(gè)點(diǎn)D的坐標(biāo)形如:

x
y
z
1

給他施加一個(gè)translate矩陣之后就可以得到的結(jié)果為 T*D :

1*x + 0*y + 0 * z + dx,               x + dx
0*x + 1*y + 0 * z + dy, = y + dy
0*x + 0*y + 1 * z + dz, z + dz
0 + 0 + 0 + 1, 1

以上的變換寫(xiě)成matrix3d函數(shù)的形式就是:matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, dx, dy, dz, 1)
等價(jià)于:
translate3d(x,y,z)。

變換矩陣的前三行可以分別看做一個(gè)空間坐標(biāo)系上對(duì)某個(gè)點(diǎn)要施以某種變換的x,y,z軸上的表示,每一行的前三列代表x,y,z軸上具體要有的變換,比如在位移變換矩陣中第一行代表x軸上該點(diǎn)要做的變換,那么對(duì)應(yīng)的y,z的值為0。(這是我個(gè)人的一點(diǎn)思考。可跳過(guò)。。。)

scale

scale表示的是一個(gè)縮放變換,縮放的具體數(shù)值體現(xiàn)在主對(duì)角線上,比如一個(gè)1.5倍的縮放矩陣S:

1.5   0   0   0
0 1.5 0 0
0 0 1.5 0
0 0 0 1

給上邊的點(diǎn)D施加一個(gè)縮放矩陣得到的結(jié)果是 S*D:

1.5*x + 0*y   + 0*z  + 0 * 1      1.5x
0*x + 1.5*y + 0*z + 0 * 1 = 1.5y
0*x + 0*y + 1.5*z + 0 * 1 1.5z
0*x + 0*y + 0*z + 1 * 1 1

等價(jià)于:matrix3d(1.5, 0, 0, 0, 0, 1.5, 0, 0, 0, 0, 1.5, 0, 0, 0, 0, 1)
可簡(jiǎn)寫(xiě)為:
scale3d(1.5, 1.5, 1.5)

rotate

rotate 代表旋轉(zhuǎn)

二維平面的rotate

二維平面的rotate代表某個(gè)點(diǎn)繞著某個(gè)點(diǎn)旋轉(zhuǎn),一個(gè)二維變換可以使用一個(gè)三階齊次矩陣表示,其矩陣的推導(dǎo)可以這么推導(dǎo):

首先是主對(duì)角線上的縮放數(shù)值,和第三列的位移值,都為默認(rèn)值1(代表原始大?。┖?(代表原始位置):

1 0 0
0 1 0
0 0 1

我們拿如下二維坐標(biāo)系舉例:
將兩個(gè)單位向量分別在x y軸上旋轉(zhuǎn)θ角度,得到的A’便是x軸上旋轉(zhuǎn)矩陣的值,得到的B’ 便是y軸上旋轉(zhuǎn)矩陣的值,因此2d的旋轉(zhuǎn)矩陣是這樣的(圖片上的坐標(biāo)系是以行向量表示的,為了統(tǒng)一 我們進(jìn)行一次轉(zhuǎn)置):

cos0 -sin0
sin0 cos0

3d空間的rotate

在一個(gè)3d空間中,旋轉(zhuǎn)不再是繞某個(gè)點(diǎn)的旋轉(zhuǎn),而是繞某個(gè)軸的旋轉(zhuǎn)(x,y,z軸),以繞x軸的旋轉(zhuǎn)舉例(這個(gè)圖有點(diǎn)出入,實(shí)際BB’應(yīng)該與y軸是平行的,AA’與Z軸平行,理解就好,沒(méi)辦法繪畫(huà)功底實(shí)在太差 - -,繞某個(gè)軸旋轉(zhuǎn)就是想象該條軸不動(dòng)然后另一條與他垂直地軸繞著其旋轉(zhuǎn)):
因此繞x軸的旋轉(zhuǎn)矩陣可以寫(xiě)成這樣:

1 0 0 0
0 cos0 -sin0 0
0 sin0 cos0 0
0 0 0 1

我們可以寫(xiě)一個(gè)rotateX(60deg),那么對(duì)應(yīng)的matrix3d的參數(shù)就是:
matrix3d(1, 0, 0, 0, 0, 0.5, 0.866025, 0, 0, -0.866025, 0.5, 0, 0, 0, 0, 1)
同理可以得出繞z軸和y軸的旋轉(zhuǎn)矩陣:

Z:

cos0 -sin0 0 0
sin0 cos0 0 0
0 0 1 0
0 0 0 1

Y

cos0 0 sin0 0
0 1 0 0
-sin0 0 cos0 0
0 0 0 1

至此,css中的3d變換大體上講完了,然后將以上幾種矩陣經(jīng)過(guò)不同組合相乘就能得到復(fù)合變換,值得注意的是 矩陣乘法一般不滿足交換律,所以運(yùn)算順序還是比較重要的。

那為什么圖形變換在計(jì)算機(jī)中一般使用矩陣表示呢?據(jù)我現(xiàn)在看到的資料來(lái)看,就是方便,使用矩陣運(yùn)算之后,可以將多種變換統(tǒng)一成矩陣的乘法運(yùn)算,方便計(jì)算機(jī)流水線式處理。
最后回答一下第二個(gè)問(wèn)題:

為什么硬件加速要使用transform,以及為什么硬件加速會(huì)快?
第一點(diǎn)是因?yàn)閏ss的3d transform屬性使用在一個(gè)元素上該元素會(huì)被提升成一個(gè)單獨(dú)的layer,在一個(gè)單獨(dú)的layer上使用一些變換可以直接跳過(guò)瀏覽器渲染的一般流程layout,paint,直接在計(jì)算結(jié)束之后進(jìn)行一次composite ,這是快的第一點(diǎn), 第二點(diǎn)是因?yàn)槭褂胻ransform變換的元素其運(yùn)算發(fā)生在gpu上,而gpu的多核在處理并發(fā)運(yùn)算的時(shí)候本身就要比cpu快 基本是這樣。

最后分享一個(gè)矩陣的乘法運(yùn)算,可以驗(yàn)證一下css transform相關(guān)的矩陣運(yùn)算

// 矩陣相乘
function multipy(a,b){
let r = a.length;
let col = a[0].length;
let result = [];
for( let i = 0; i < r; i++ ){

let row = a[i];
result[i] = [];

for( let j = 0; j < r; j++){
let count = 0;
for( let x = 0;x < col; x++ ){
let item1 = row[x];
let item2 = b[x][j]
count += (item1*item2)
}
result[i].push(count)


}
}
return result;

}
const deg45 = Math.PI/4;

后記

image-preview是一款移動(dòng)端圖片瀏覽器插件,在這個(gè)分支的提交中 將變換矩陣直接應(yīng)用到了實(shí)際應(yīng)用中,基本的圖形變換已經(jīng)全部由變換矩陣實(shí)現(xiàn)。https://github.com/daxiazilong/imagePreview/commit/e36fc22d58d9bc32f0a414db5f75030af9832649

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2023-10-04 09:36:58

3D模型

2013-01-30 16:15:40

adobeHTML5css3

2021-06-18 05:59:37

Css前端CSS 特效

2017-07-11 15:00:04

前端CSS3D視角

2021-08-30 06:20:39

CSS 技巧3D 效果

2021-06-09 08:30:52

CSS33D旋轉(zhuǎn)視圖3D動(dòng)畫(huà)

2021-11-08 06:02:17

CSS 技巧代碼重構(gòu)

2021-01-05 08:10:00

Css前端3D旋轉(zhuǎn)透視

2012-09-12 13:23:11

麗臺(tái)VMware Vi

2012-02-24 09:11:45

jQuery

2012-06-16 16:57:52

WebGL

2012-05-10 10:55:03

CSS

2011-06-15 13:08:59

2018-03-28 09:18:35

CITE智能制造3D打印館

2011-05-26 10:55:39

2011-02-17 10:54:59

CSS3變換 簡(jiǎn)單快捷

2009-12-15 16:13:11

3D圖像

2017-09-19 14:05:24

web

2011-10-06 13:30:45

宏碁投影儀

2012-11-26 12:51:44

木材3D打
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)