WebGL第十九课:旋转及其矩阵表达(涉及数学推导)| 8月更文挑战

294 阅读3分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

本文标题:WebGL第十九课:旋转及其矩阵表达(涉及数学推导)| 8月更文挑战

引子

我们知道一个矩阵乘以一个向量,得到的结果就是一个向量。

我们把上面的概念称之为,矩阵右乘向量,也可以称为向量左乘矩阵,就是左右顺序是有规定的。这一点可以从矩阵乘法就是线性组合的概念中去理解。不理解的小伙伴可以去看前面的课程

重点:向量左乘矩阵之后,能变成一个新的向量。

也就是说,我们选用不同的矩阵,就能得到不同的向量。

在上次课,我们找到了一个矩阵,能够让我们得到拉伸之后的向量,即如下矩阵:

[a00b]\begin{bmatrix} a & 0 \\ 0 & b \end{bmatrix}

[a00b]\begin{bmatrix} a & 0 \\ 0 & b \end{bmatrix} * (xy)=(axby)\left(\begin{array}{cc} x\\ y\end{array}\right) = \left(\begin{array}{cc} a * x\\ b * y\end{array}\right)

用大白话说就是,(xy)\left(\begin{array}{cc} x\\ y\end{array}\right) 这个向量,左乘 [a00b]\begin{bmatrix} a & 0 \\ 0 & b \end{bmatrix} 这个矩阵之后,变成了 (axby)\left(\begin{array}{cc} a * x\\ b * y\end{array}\right), xx 拉伸了aa倍,yy拉伸了bb倍。

那么这次课,主要就是来找到一个矩阵,任意一个向量左乘这个矩阵之后,得到的新向量,都是原向量绕原点进行逆时针旋转之后的效果。

寻找旋转矩阵

第十课,我们利用勾股定理给出了一个向量A:(xy)\left(\begin{array}{cc} x\\ y\end{array}\right),绕着原点进行逆时针旋转α弧度之后的结果是向量B : (xcos(α)ysin(α)xsin(α)+ycos(α))\left(\begin{array}{cc} x * cos(α) - y * sin(α)\\ x * sin(α) + y * cos(α)\end{array}\right)

那现在我们就是要找到一个矩阵 [acbd]\begin{bmatrix} a & c \\ b & d \end{bmatrix},使得下面的等式成立:

[acbd]\begin{bmatrix} a & c \\ b & d \end{bmatrix} * (xy)\left(\begin{array}{cc} x\\ y\end{array}\right) = (xcos(α)ysin(α)xsin(α)+ycos(α))\left(\begin{array}{cc} x * cos(α) - y * sin(α)\\ x * sin(α) + y * cos(α)\end{array}\right)

上面的等式,对于所有的(xy)\left(\begin{array}{cc} x\\ y\end{array}\right)都要成立,所以我们可以任意带入数值,去联立解方程,这在上次课已经说了。

选取 x = 1, y = 0

[acbd]\begin{bmatrix} a & c \\ b & d \end{bmatrix} * (10)\left(\begin{array}{cc} 1\\ 0\end{array}\right) = (1cos(α)0sin(α)1sin(α)+0cos(α))\left(\begin{array}{cc} 1 * cos(α) - 0 * sin(α)\\ 1 * sin(α) + 0 * cos(α)\end{array}\right)

(ab)1+(cd)0=(cos(α)sin(α))\left(\begin{array}{cc} a\\ b\end{array}\right) * 1 + \left(\begin{array}{cc} c\\ d\end{array}\right) * 0 = \left(\begin{array}{cc} cos(α)\\ sin(α)\end{array}\right)

(ab)=(cos(α)sin(α))\left(\begin{array}{cc} a\\ b\end{array}\right) = \left(\begin{array}{cc} cos(α)\\ sin(α)\end{array}\right)

选取 x = 0, y = 1

[acbd]\begin{bmatrix} a & c \\ b & d \end{bmatrix} * (01)\left(\begin{array}{cc} 0\\ 1\end{array}\right) = (0cos(α)1sin(α)0sin(α)+1cos(α))\left(\begin{array}{cc} 0 * cos(α) - 1 * sin(α)\\ 0 * sin(α) + 1 * cos(α)\end{array}\right)

(ab)0+(cd)1=(sin(α)cos(α))\left(\begin{array}{cc} a\\ b\end{array}\right) * 0 + \left(\begin{array}{cc} c\\ d\end{array}\right) * 1 = \left(\begin{array}{cc} -sin(α)\\ cos(α)\end{array}\right)

(cd)=(sin(α)cos(α))\left(\begin{array}{cc} c\\ d\end{array}\right) = \left(\begin{array}{cc} -sin(α)\\ cos(α)\end{array}\right)

得出结论

至此,我们找到了旋转矩阵,即

[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix} * (xy)\left(\begin{array}{cc} x\\ y\end{array}\right) = (xcos(α)ysin(α)xsin(α)+ycos(α))\left(\begin{array}{cc} x * cos(α) - y * sin(α)\\ x * sin(α) + y * cos(α)\end{array}\right)

多个向量通过矩阵变成相应的新向量

我们上面写的矩阵右乘一个向量,代表了一个向量经过矩阵运算之后,变成了一个新的向量。

如果我们要表达多个向量都经过这个矩阵运算,变成多个新的向量,怎么办?

这其实是一个表达的问题,

例如 A 向量 (xaya)\left(\begin{array}{cc} x_a\\ y_a\end{array}\right) 经过旋转矩阵[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix}运算之后变成 A'(xaya)\left(\begin{array}{cc} x_a'\\ y_a'\end{array}\right)

我们这样表达:[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix} * (xaya)\left(\begin{array}{cc} x_a\\ y_a\end{array}\right) = (xaya)\left(\begin{array}{cc} x_a'\\ y_a'\end{array}\right)

B 向量 (xbyb)\left(\begin{array}{cc} x_b\\ y_b\end{array}\right) 经过旋转矩阵[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix}运算之后变成 B'(xbyb)\left(\begin{array}{cc} x_b'\\ y_b'\end{array}\right)

我们这样表达:[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix} * (xbyb)\left(\begin{array}{cc} x_b\\ y_b\end{array}\right) = (xbyb)\left(\begin{array}{cc} x_b'\\ y_b'\end{array}\right)

其实上面两个向量都经过一个矩阵运算,变成了相应的新的向量,我们可以合起来写:

[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix} * (xaya)(xbyb)\left(\begin{array}{cc} x_a\\ y_a\end{array}\right)\left(\begin{array}{cc} x_b\\ y_b\end{array}\right) = (xaya)(xbyb)\left(\begin{array}{cc} x_a'\\ y_a'\end{array}\right)\left(\begin{array}{cc} x_b'\\ y_b'\end{array}\right)

为了看起来不混淆,搞的好像是连乘一样,我们就把后面两个向量,合并写作:

[cos(α)sin(α)sin(α)cos(α)]\begin{bmatrix} cos(α) & -sin(α) \\ sin(α) & cos(α) \end{bmatrix} * [xaxbyayb] \begin{bmatrix} x_a & x_b \\ y_a & y_b \end{bmatrix}= [xaxbyayb] \begin{bmatrix} x_a' & x_b' \\ y_a' & y_b' \end{bmatrix}

大家看见了吗,这就是矩阵乘以矩阵的由来。早在前面就说过了,要把矩阵看做一列一列的向量,不要看做一个一个的数。这就是最根本的原因了。




  正文结束,下面是答疑

小丫丫:矩阵就是一列一列的向量,矩阵就是一列一列的向量,矩阵就是一列一列的向量(三遍)

  • 答:重要的事要每天三遍, O(∩_∩)O哈哈~