threejs系列之:矩阵推导🎰

写在最前

往期回顾:

  1. # threejs系列: 相机与投影 📷
  2. # threejs系列: 光源与光照🪀
  3. # threejs系列: 自定义几何体🎃
  4. # threejs系列: 几何变换(上)🍺
  5. # threejs系列: 几何变换(下)🏄‍♂️
  6. threejs系列: 矩阵推导🎰
  7. threejs系列: 物体详解🐧
  8. threejs系列: 材质与贴图详解🦥
  9. threejs系列: 曲线详解🥓
  10. threejs系列: 动画详解🧠
  11. …….

高强度持续更新,从0到1深入了解 threejs 的奥秘,喜欢的点个关注呀

矩阵

数学上,矩阵定义为是一个有m行(row)n列(column)元素的矩形阵列。在线性代数中矩阵和向量是随处可见的,向量与矩阵的计算也是该熟记的。

下面是一个3 * 3的矩阵。

{123456789} \left\{ \begin{matrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \end{matrix} \right\}

矩阵加法

矩阵的加减法很简单,只需要把相对位置算数就可以,前提是矩阵的行列数相同

{14}+{25}={1+24+5}={39} \left\{ \begin{matrix} 1\\ 4\\ \end{matrix} \right\}

+

\left\{ \begin{matrix} 2\\ 5\\\end{matrix} \right\}

=

\left\{ \begin{matrix} 1 + 2\\ 4 + 5\\\end{matrix} \right\}

=

\left\{ \begin{matrix} 3\\ 9\\\end{matrix} \right\}

矩阵乘法

矩阵乘以一个数字:

{14}4={1444}={416} \left\{ \begin{matrix} 1\\ 4\\ \end{matrix} \right\}

*

4

=

\left\{ \begin{matrix} 1 * 4\\ 4 * 4\\\end{matrix} \right\}

=

\left\{ \begin{matrix} 4\\ 16\\\end{matrix} \right\}

矩阵与矩阵相乘:

前提:只有第一个矩阵的列的个数等于第二个矩阵的行的个数,这样的两个矩阵才能相乘。

A矩阵与B矩阵两个矩阵相乘得到的矩阵,会有矩阵A有相同的行数,会有矩阵B相同的列数。

例如:

threejs系列之:矩阵推导🎰

2 * 3 矩阵 与 3 * 2 矩阵得到的就是一个 2 行 2 列的矩阵。

然后以分别进行 红蓝 、 红绿 、 橙蓝 、 橙绿组合进行点乘。

{abcdfe}{hijklm}={ah+bj+clai+bk+cmdh+fj+eldi+fk+em}\left\{ \begin{matrix} a & b & c\\ d & f & e\\ \end{matrix} \right\}

*

\left\{ \begin{matrix} h & i\\ j & k\\l & m\\\end{matrix} \right\}

=

\left\{ \begin{matrix} a * h + b * j + c* l & a * i + b * k + c * m\\ d * h + f * j + e * l & d * i + f * k + e * m\\\end{matrix} \right\}

以上就是矩阵的简单计算。

向量

在上篇文章我们讲到的向量其实也能看作是一个m * 1的矩阵,比如:

向量[x,y,z]={xyz}向量 [x, y, z] = \left\{ \begin{matrix} x\\ y\\ z\\ \end{matrix} \right\}

在几何平面上:

threejs系列之:矩阵推导🎰

ojy坐标的单位向量,oix坐标的单位向量,oA可以表示为3oi+2oj\vec{oj} 为y坐标的单位向量,\vec{oi}为x坐标的单位向量,\vec{oA}可以表示为 3\vec{oi} + 2\vec{oj}

则矩阵表示的话是为:3{10}+2{01}={31+2030+21}={32}则矩阵表示的话是为: 3

\left\{ \begin{matrix} 1\\ 0\\ \end{matrix} \right\}

+

2

\left\{ \begin{matrix} 0\\ 1\\ \end{matrix} \right\}

=

\left\{ \begin{matrix} 3 * 1 + 2* 0\\ 3 * 0 + 2 * 1\\ \end{matrix} \right\}

=

\left\{ \begin{matrix} 3\\ 2\\ \end{matrix} \right\}

=

计算方式和矩阵如出一辙{1001}{32}={31+2030+21}={32}计算方式和矩阵如出一辙 \left\{ \begin{matrix} 1 & 0\\ 0 & 1\\ \end{matrix} \right\}

\left\{ \begin{matrix} 3\\ 2\\ \end{matrix} \right\}

=

\left\{ \begin{matrix} 3 * 1 + 2* 0\\ 3 * 0 + 2 * 1\\ \end{matrix} \right\}

=

\left\{ \begin{matrix} 3\\ 2\\ \end{matrix} \right\}

这里由两个坐标系单位向量组成的矩阵也被称之为单位矩阵

{1001} \left\{ \begin{matrix} 1 & 0\\ 0 & 1\\ \end{matrix} \right\}

图中的 ojoi \vec{oj} 和 \vec{oi} 也被称为坐标系的基向量

旋转矩阵推导

将坐标轴逆时针旋转45°

threejs系列之:矩阵推导🎰

oi由旋转公式可得:{cos45°sin45°}oj={sin45°cos45°}\vec{oi}由旋转公式可得: \left\{ \begin{matrix} cos45°\\ sin45°\\ \end{matrix} \right\} , \vec{oj} = \left\{ \begin{matrix} -sin45°\\ cos45°\\ \end{matrix} \right\}

矩阵表示为:

{cos45°sin45°sin45°cos45°}{32}\left\{ \begin{matrix} cos45° & -sin45°\\ sin45° & cos45°\\ \end{matrix} \right\}

\left\{ \begin{matrix} 3\\ 2\\ \end{matrix} \right\}

所以平面旋转矩阵为:

{cos45°sin45°sin45°cos45°}\left\{ \begin{matrix} cos45° & -sin45°\\ sin45° & cos45°\\ \end{matrix} \right\}

缩放矩阵推导

我们将坐标系缩小2倍

threejs系列之:矩阵推导🎰

oi此时坐标:{1/z0}oj={01/z},又因为OA=3Oi+2Oj,所以矩阵表示为:{1/z001/z}{32}\vec{oi}此时坐标: \left\{ \begin{matrix} 1 / z\\ 0\\ \end{matrix} \right\} , \vec{oj} = \left\{ \begin{matrix} 0\\ 1 / z\\ \end{matrix} \right\} , 又因为\vec{OA} = 3\vec{Oi} + 2\vec{Oj},

所以矩阵表示为:

\left\{ \begin{matrix} 1 / z & 0\\ 0 & 1 / z\\\end{matrix} \right\}

\left\{ \begin{matrix} 3\\ 2\\\end{matrix} \right\}

缩放矩阵为:

{z00z}\left\{ \begin{matrix} z & 0\\ 0 & z\\ \end{matrix} \right\}

线性变换

你会发现这种变换坐标系然后通过基向量获取点向量的方式很有趣,这种方式在数学中叫做线性变换

线性变换在几何直观上有如下特点:

  • 变换前后,直线仍然保持是直线的状态
  • 变换前后,原点保持固定,不会变化

平移矩阵推导

仿射变换

由于线性变换拥有原点固定的特点,所以无法进行平移,只能旋转和缩放。

一刻也无需为无法平移感伤,接下来出场的是 仿射变换

仿射变换与线性变换的最大不同就是原点可以移动

通过添加一个维度进行线性变换然后在低纬度上投影,这样看上去就是在低纬度上移动了。

threejs系列之:矩阵推导🎰

这张图形象的说明了仿射变换。

齐次坐标

齐次坐标就是将原先 n 维坐标改成 n + 1 维坐标表示。在3d图形学中,我们需要在向量中添加一个分量叫做 w ,表示在4维空间中的位置。物体的坐标其实是
(x/w, y/w ,z/w),因此当 w = 1 时,物体的xyz不会变化,所以通常我们都将 w 设置为1。

推导

我们回到平移推导,我们假设将坐标(x,y)平移到坐标(x’,y’),因为线性变换无法平移,所以我们需乘以一个未知的齐次平移矩阵

{xyz}{abcdefgh1}={ax+by+czdx+ey+fzgx+hy+iz} \left\{ \begin{matrix} x\\ y\\ z\\ \end{matrix} \right\}

*

\left\{ \begin{matrix} a & b & c\\ d & e & f\\g & h & 1\\\end{matrix} \right\}

=

\left\{ \begin{matrix} ax + by + cz\\ dx + ey + fz\\gx + hy + iz\\\end{matrix} \right\}

得到以下等式

x' = ax + by + cz;
y' = dx + ey + fz;
1  = gx + hy + z;

从式子我们可以首先得出 g = 0, h = 0, z = 1;

因为是平移,所以我们知道x’是 x移动了Tx, y’是y移动了Ty

x' = x + Tx;
y' = y + Tx;

所以上面两个等式结合,我们可以知道,a = 1,b = 0, cz = Tx;d = 0, e = 1,f = Ty。

将其带入后得到平移矩阵

{10Tx01Ty001} \left\{ \begin{matrix} 1 & 0 & Tx\\ 0 & 1 & Ty\\ 0 & 0 & 1\\ \end{matrix} \right\}

至此,三个基础得几何转换矩阵都得出来了,这里不禁感叹道还真是不容易呢😅

threejs 矩阵

矩阵的计算是相对复杂得,幸运的是threejs为我们封装了数学方法,接下来我们看看threejs如何使用矩阵。

threejs提供了Matrix4 类让我们快速的创建一个 4*4 矩阵。

m4 = new THREE.Matrix4();

然后通过.set方法进行填充元素。

m4.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);

通过.element方法查看元素

m4.element

threejs系列之:矩阵推导🎰

我们来进行矩阵进行几何变换:

// 缩放
mesh.matrix.makeScale(0.5, 0.5, 0.5);
mesh.matrixAutoUpdate = false;

API就不一一讲了,都是易懂的。

原文链接:https://juejin.cn/post/7317827078114918427 作者:兰奇

(0)
上一篇 2023年12月29日 下午4:11
下一篇 2023年12月29日 下午4:21

相关推荐

发表回复

登录后才能评论