前言
前面Web二维矩阵matrix详解我们已经说过了二维矩阵了,现在我们来说下三维空间当中的矩阵吧~
一、3D平面的矩阵由来?
我们的3D平面坐标系,有x,y,z三个坐标体系,那么不管我们怎么对图片进行变换,归根结底都是对x,y,z 坐标的变换。
对于三维我们使用的是一个4x4的矩阵,类似这样:
(
a
00
a
01
a
02
a
03
a
10
a
11
a
12
a
13
a
20
a
21
a
22
a
23
a
30
a
31
a
32
a
33
)
\begin{pmatrix} a_{00} & a_{01} & a_{02} & a_{03} \\ a_{10} & a_{11} & a_{12} & a_{13} \\ a_{20} & a_{21} & a_{22} & a_{23} \\ a_{30} & a_{31} & a_{32} & a_{33} \end{pmatrix}
⎝⎜⎜⎛a00a10a20a30a01a11a21a31a02a12a22a32a03a13a23a33⎠⎟⎟⎞
在计算的时候我们以该矩阵乘以我们的位置矩阵,因为三维当中只有x,y,z三个值。但要进行计算需要4个值,所以我们将第4个值设置为1。就可以的到我们的位置矩阵:
(
x
y
z
1
)
\begin{pmatrix} x \\ y \\ z \\ 1 \end{pmatrix}
⎝⎜⎜⎛xyz1⎠⎟⎟⎞
在该例中,即是:
{
n
e
w
X
=
a
00
∗
x
+
a
01
∗
y
+
a
02
∗
z
+
a
03
∗
1
n
e
w
Y
=
a
10
∗
x
+
a
11
∗
y
+
a
12
∗
z
+
a
13
∗
1
n
e
w
Z
=
a
20
∗
x
+
a
21
∗
y
+
a
22
∗
z
+
a
23
∗
1
e
x
t
r
a
=
a
30
∗
x
+
a
31
∗
y
+
a
32
∗
z
+
a
33
∗
1
①
\begin{cases} newX=a_{00}*x+a_{01} *y+a_{02}*z+ a_{03}*1\\ newY=a_{10}*x+a_{11} *y+a_{12}*z+ a_{13}*1 \\ newZ=a_{20}*x+a_{21} *y+a_{22}*z+ a_{23}*1 \\ extra=a_{30}*x+a_{31} *y+a_{32}*z+ a_{33}*1 \end{cases} ①
⎩⎪⎪⎪⎨⎪⎪⎪⎧newX=a00∗x+a01∗y+a02∗z+a03∗1newY=a10∗x+a11∗y+a12∗z+a13∗1newZ=a20∗x+a21∗y+a22∗z+a23∗1extra=a30∗x+a31∗y+a32∗z+a33∗1①
好像单从这里也看不出来什么,下面我们来一步一步的使用矩阵完成CSS API中的平移,缩放,旋转,斜切吧,从中你就应该有所体会了。
二、平移
假设我们需要对3D平面中一个点(x,y,z)进行平移,在三个方向平移的量为tx,ty,tz,得到新点的坐标(x1,y1,z1)。
公式推导
因为只是简单的移动x,y,z轴,所以:
{
x
1
=
x
+
t
x
y
1
=
y
+
t
y
z
1
=
z
+
t
z
②
\begin{cases} x_1=x+tx \\ y_1=y+ty \\ z_1=z+tz \end{cases} ②
⎩⎪⎨⎪⎧x1=x+txy1=y+tyz1=z+tz②
推导矩阵
由①据②可得各参数取值:
{
a
00
=
1
a
01
=
0
a
02
=
0
a
03
=
t
x
a
10
=
0
a
11
=
1
a
12
=
0
a
13
=
t
y
a
20
=
0
a
21
=
0
a
22
=
1
a
23
=
t
z
\begin{cases} a_{00}=1 \\ a_{01}=0 \\ a_{02}=0 \\ a_{03}=tx \\ a_{10}=0 \\ a_{11}=1 \\ a_{12}=0 \\ a_{13}=ty \\ a_{20}=0 \\ a_{21}=0 \\ a_{22}=1 \\ a_{23}=tz \\ \end{cases}
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧a00=1a01=0a02=0a03=txa10=0a11=1a12=0a13=tya20=0a21=0a22=1a23=tz
因为只需关注x,y,z,所以可取得我们的一个平移矩阵:
(
1
0
0
t
x
0
1
0
t
y
0
0
1
t
z
0
0
0
1
)
\begin{pmatrix} 1 & 0 & 0 & tx \\ 0 & 1 & 0 & ty \\ 0 & 0 & 1 & tz \\ 0 & 0 & 0 & 1 \end{pmatrix}
⎝⎜⎜⎛100001000010txtytz1⎠⎟⎟⎞
从这里可以看出,影响我们平移x,y,z变化的在矩阵中红框中的位置:
三、缩放
假设我们需要对3D平面中坐标原点到一个点A(x,y,z)所在的线段进行缩放,缩放的比例为各自为bx,by,bz,那么A对应的新点的坐标B(x1,y1,z1)。
公式推导
因为只是简单的缩放x,y,z轴,所以:
{
x
1
=
x
∗
b
x
y
1
=
y
∗
b
y
z
1
=
z
∗
b
z
③
\begin{cases} x_1=x*b_x \\ y_1=y*b_y \\ z_1=z*b_z \end{cases} ③
⎩⎪⎨⎪⎧x1=x∗bxy1=y∗byz1=z∗bz③
推导矩阵
由①据③可得各参数取值:
{
a
00
=
b
x
a
01
=
0
a
02
=
0
a
03
=
0
a
10
=
0
a
11
=
b
y
a
12
=
0
a
13
=
0
a
20
=
0
a
21
=
0
a
22
=
b
z
a
23
=
0
\begin{cases} a_{00}=b_x \\ a_{01}=0 \\ a_{02}=0 \\ a_{03}=0 \\ a_{10}=0 \\ a_{11}=b_y \\ a_{12}=0 \\ a_{13}=0 \\ a_{20}=0 \\ a_{21}=0 \\ a_{22}=b_z \\ a_{23}=0 \end{cases}
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧a00=bxa01=0a02=0a03=0a10=0a11=bya12=0a13=0a20=0a21=0a22=bza23=0
因为只需关注x,y,z,所以可取得我们的一个缩放矩阵:
(
b
x
0
0
0
0
b
y
0
0
0
0
b
z
0
0
0
0
1
)
\begin{pmatrix} b_x & 0 & 0 & 0 \\ 0 & b_y & 0 & 0 \\ 0 & 0 & b_z & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}
⎝⎜⎜⎛bx0000by0000bz00001⎠⎟⎟⎞
从这里可以看出,影响我们缩放x,y,z变化的在矩阵中红框中的位置:
四、旋转
假设我们需要对3D平面中一个点(x,y)围绕一个轴(例如Z)的进行旋转,旋转的角度为β,得到新点的坐标(x1,y1)。
要得到新点的坐标,首先我们需要理解一个概念:
单位圆
- 在平面直角坐标系中,圆心在原点,半径为1的圆即是我们的单位圆。
- 由1,当我们已经一个点的与圆心的连线的角度时(假设为α),那么我们可以求得他的坐标为(cos(α),sin(a))。
- 由2,现在我们把这个单位圆扩展到以坐标原点为圆心,半径为r的圆上任意一点。假设一点的偏转角度为α,那么得出该坐标为(r * cos(α),r * sin(a))
公式推导
由单位圆的概念,假定我们要移动的点(x,y)与坐标原点构成的半径为r的圆中,该点的偏转角度为a,那么把该点旋转β度之后,得到的新点(x1,y1)的坐标旋转角度应该是(α+β)度,由此我们可得到一个公式:
{
x
=
r
∗
c
o
s
(
α
)
y
=
r
∗
s
i
n
(
α
)
x
1
=
r
∗
c
o
s
(
α
+
β
)
=
r
∗
c
o
s
α
c
o
s
β
−
r
∗
s
i
n
α
s
i
n
β
y
1
=
r
∗
s
i
n
(
α
+
β
)
=
r
∗
s
i
n
(
α
)
c
o
s
(
β
)
+
r
∗
c
o
s
(
α
)
s
i
n
(
β
)
\begin{cases} x= r * cos(α) \\ y= r * sin(α) \\ x_1= r * cos(α+β) =r*cosαcosβ-r*sinαsinβ\\ y_1= r * sin(α+β) =r * sin(α) cos(β)+r*cos(α)sin(β) \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧x=r∗cos(α)y=r∗sin(α)x1=r∗cos(α+β)=r∗cosαcosβ−r∗sinαsinβy1=r∗sin(α+β)=r∗sin(α)cos(β)+r∗cos(α)sin(β)
简化得到:
{
x
1
=
x
∗
c
o
s
β
−
y
∗
s
i
n
β
y
1
=
x
∗
s
i
n
(
β
)
+
y
∗
c
o
s
(
β
)
④
\begin{cases} x_1= x*cosβ-y*sinβ\\ y_1= x*sin(β) +y*cos(β) \end{cases} ④
{x1=x∗cosβ−y∗sinβy1=x∗sin(β)+y∗cos(β)④
推导矩阵
绕Z轴旋转
因为绕Z轴旋转,故不考虑Z轴,只关注x,y坐标的变化,可得类似下面的平面坐标系。
旋转β度,可见旋转方向为x->y的方向(顺时针)。
由①据④可得各参数取值:
{
a
00
=
c
o
s
(
β
)
a
01
=
−
s
i
n
(
β
)
a
02
=
0
a
03
=
0
a
10
=
s
i
n
(
β
)
a
11
=
c
o
s
(
β
)
a
12
=
0
a
13
=
0
\begin{cases} a_{00}= cos(β)\\ a_{01}=-sin(β) \\ a_{02}=0\\ a_{03}=0\\ a_{10}= sin(β)\\ a_{11}=cos(β) \\ a_{12}=0\\ a_{13}=0 \end{cases}
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧a00=cos(β)a01=−sin(β)a02=0a03=0a10=sin(β)a11=cos(β)a12=0a13=0
因为只需关注x,y,所以可取得我们的一个缩放矩阵:
(
c
o
s
(
β
)
−
s
i
n
(
β
)
0
0
s
i
n
(
β
)
c
o
s
(
β
)
0
0
0
0
1
0
0
0
0
1
)
\begin{pmatrix} cos(β) & -sin(β) & 0 & 0 \\ sin(β) & cos(β) & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}
⎝⎜⎜⎛cos(β)sin(β)00−sin(β)cos(β)0000100001⎠⎟⎟⎞
从这里可以看出,影响我们缩放x,y变化的在矩阵中红框中的位置:
绕X轴旋转
因为绕X轴旋转,故不考虑X轴,只关注y,z坐标的变化,可得类似下面的平面坐标系。
旋转β度,可见旋转方向为y->z的方向(顺时针)。
由绕Z轴旋转同理可得:影响我们缩放y,z变化的在矩阵中红框中的位置:
绕Y轴旋转
因为绕Y轴旋转,故不考虑Y轴,只关注x,z坐标的变化,可得类似下面的平面坐标系。
旋转β度,可见旋转方向为x->z的方向(逆时针)。
由绕Z轴旋转同理可得:影响我们缩放x,z变化的在矩阵中红框中的位置:
注意:三维坐标体系中绕Y轴旋转时和绕X和Z轴方向不一致,所以参数有些微差异。
结论
我们发现影响旋转的就是
图中红框所在的位置,具体可以对应上面的查看。
因为我们已经得到了三个方向的各个矩阵。那么通过矩阵乘法,我们即可得到一个同时三个方向都旋转的矩阵。
五、CSS3中matrix3d() 使用
到这里,你应该对CSS中的矩阵有了一个比较清晰的理解了。那么我们来看下CSS中的matrix。
可以发现,matrix3d() API 中,有16个参数,但是他的参数的顺序和我们上面给出的顺序并不相同,上面给出的是数学中的矩阵的正常格式:
行(row)是横向的,列(column)是纵先的。但是Web当中矩阵是刚好相反,即列是横向的,行是纵向的。类似下面这样:
所以大家应该注意,前文所有的推导结果,放到matrix3d中,顺序应该是下面这样:
matrix3d(,a00,a10,a20,a30,a01,a11,a21,a31,a02,a12,a22,a32,a03,a13,a23,a33)。
总结
到这里,我们就对三维矩阵有了个清晰的认识了,不过一般也用不到,有其他已经封装好的API,translate3d,scale3d,rotate3d等。不过我们要进一步提高自己的技术,还是应该知其然,也知其所以然。