WebGl矩阵的运用

学会运用矩阵,在二维三维中即可实现移动、旋转、缩放。
还可清晰掌握图形方向,代码结构更清晰简短

矩阵

■ 加法运算

矩阵的加减法运算基于阵列尺寸相同,若不相同是无法计算的,也没有意义。
但可以将不同尺寸的矩阵转换成相同尺寸后进行运算,较为灵活
如下,用大腿思考一下也能知道仅仅只是把相同位置进行了加法运算得出结果

$$
\begin {pmatrix}
1 & 2 & 3 \newline
4 & 5 & 6 \newline
7 & 8 & 9
\end {pmatrix}
+
\begin {pmatrix}
1 & 2 & 3 \newline
4 & 5 & 6 \newline
7 & 8 & 9
\end {pmatrix}
=
\begin {pmatrix}
2 & 4 & 6 \newline
8 & 10 & 12 \newline
14 & 16 & 18
\end {pmatrix}
$$

■ 减法运算

如下, 用屁股思考也知道,和加法运算一样,相同位置进行了减法计算

$$
\begin {pmatrix}
1 & 2 & 3 \newline
4 & 5 & 6 \newline
7 & 8 & 9
\end {pmatrix}
-
\begin {pmatrix}
1 & 2 & 3 \newline
4 & 5 & 6 \newline
7 & 8 & 9
\end {pmatrix}
=
\begin {pmatrix}
0 & 0 & 0 \newline
0 & 0 & 0 \newline
0 & 0 & 0
\end {pmatrix}
$$

■ 乘法运算

  • 矩阵乘以数字

$$
\begin {pmatrix}
1 & 2 \newline
3 & 4
\end {pmatrix}
*
0.5
=
\begin {pmatrix}
0.5 & 1 \newline
1.5 & 2
\end {pmatrix}
$$

直接和矩阵中每个数字相乘,跟吃饼一样简单
注意: 矩阵计算中应该把除法转为乘法运算

  • 矩阵乘以矩阵

运算较为复杂,大腿和屁股的算力已经无法支持了,这里将把详细运算步骤记录下来说明

$$
\begin {pmatrix}
a & b & c \newline
d & e & f \newline
g & h & i
\end {pmatrix}
\begin {pmatrix}
j & k & l \newline
m & n & o \newline
p & q & r
\end {pmatrix}
=
\begin {pmatrix}
aj + bm + cp & ak + bn + cq & al + bo + cr \newline
dj + em + fp & dk + en + fq & dl + eo + fr \newline
gj + hm + ip & gk + hn + iq & gl + ho + ir
\end {pmatrix}
$$

比加减法稍微复杂一些,但只要记住规律并不算复杂

结果中的任意位置x都等于x所在的左边的矩阵同行和右边矩阵同列的逐个相乘后相加


为了加深对矩阵的了解,又查阅了一些文章,原来:

矩阵的最初目的,只是为线性方程组提供一个简写形式, 有兴趣的可以再查一下线性方程

$$
\begin {cases}
2x + y = 3 \newline
4x + 3y = 7 \newline
\end {cases}
$$

转换为

$$
\begin {pmatrix}
2 & 1 \newline
4 & 3
\end {pmatrix}
\begin {pmatrix}
x \newline
y
\end {pmatrix}
=
\begin {pmatrix}
3 \newline
7
\end {pmatrix}
$$

这样看就很容易理解了,


不排除还有没理解的同学
这里有一篇文章《矩阵乘法》 详细介绍了矩阵的乘法
不管你是精通了还是初学,这都是一篇非常极品的文章,推荐阅读!


运用

■ 矩阵运算的好处

常规的运算不仅复杂多变,GLSL的写法也相应复杂起, 随着图形的增加及应用的深入
代码不仅阅读困难,调试也是噩梦
而矩阵可以将所以这些操作算法做统一处理,且让代码易于阅读调试, 统一的算法也大大地加快了计算速度

看了webglfundamentals的文章 - WebGL 二维矩阵
介绍矩阵的用法非常突兀,刚看到平移部分就一脸蒙蔽,这写的什么吊啊? 一个下午沉浸在痛苦中,不知所云。
然,并不是说这个文章不好,只不过对于我这样的初学者来说,
这篇文章需要有个理解基础和更加易于理解的文字描述,否则根本无法前进

我的理解是,关于平移的部分,利用了矩阵的特性

■ 平移

平移时,首先将现有二维坐标设为(x, y, 1)

为了达到以下公式

1
2
newX = x + tx;
newY = y + ty;

利用矩阵的特性,设计出如下3x3矩阵

$$
\begin {pmatrix}
1.0 & 0.0 & 0.0 \newline
0.0 & 1.0 & 0.0 \newline
tx & ty & 1.0
\end {pmatrix}
$$

套用以上计算公式可以得出, x轴平移时无需ty的加入, 故设为0, 最终得到 newX = x + tx, y轴同理

■ 缩放

缩放的公式为

1
2
newX = x*sx
newY = y*sy

为了掌握矩阵的应用,这里从头开始设计学习这个矩阵

$$
\begin {pmatrix}
x & y & 1
\end {pmatrix}
\begin {pmatrix}
j & k & l \newline
m & n & o \newline
p & q & r
\end {pmatrix}
=
\begin {pmatrix}
xj + ym + p, xk + yn + q, p + q + r
\end {pmatrix}
$$

我们想要的结果是 (x*sx, y*sy, 1), 如上我们要把xj即为x*sxyn即为y*sy
我们把m p k q设为0p + q + r结果为1(这里随便取r=1), 的话,即可实现这个公式
即:

$$
\begin {pmatrix}
x & y & 1
\end {pmatrix}
\begin {pmatrix}
j & 0 & 0 \newline
0 & n & 0 \newline
0 & 0 & 1
\end {pmatrix}
=
\begin {pmatrix}
xj, yn, 1
\end {pmatrix}
$$

这样我们就设计出了适合缩放的矩阵了

■ 旋转

先说一下最基础的数学公式,之前的文章有提到过,不知道大家还记得吗,反正我是不记得了,这里再列出来一下

1
2
rotatedX = a_position.x * u_rotation.y + a_position.y * u_rotation.x;
rotatedY = a_position.y * u_rotation.y - a_position.x * u_rotation.x;

如果觉得缩放的推导不好理解(确实麻烦,写的什么鬼啊我)
这个部分我们先写出线性方程,然后再直接转为矩阵

旋转只需要和旋转角对应的正弦和余弦值

1
2
s = Math.sin(angleToRotateInRadians);
c = Math.cos(angleToRotateInRadians);

$$
\begin {cases}
xc + ys = newX \newline
-xs + yc = newY \newline
\end {cases}
$$

转为矩阵

$$
\begin {pmatrix}
x & y & 1
\end {pmatrix}
\begin {pmatrix}
c & -s & 0 \newline
s & c & 0 \newline
0 & 0 & 1
\end {pmatrix}
=
\begin {pmatrix}
newX, newY, 1
\end {pmatrix}
$$

这样应该好理解了吧, 我也是恍然大悟

■ 实际运用

■ 实例代码

KEEP UPDATE

#

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×