写在最前
往期回顾:
- # threejs系列: 相机与投影 📷
- # threejs系列: 光源与光照🪀
- # threejs系列: 自定义几何体🎃
- # threejs系列: 几何变换(上)🍺
- # threejs系列: 几何变换(下)🏄♂️
- threejs系列: 矩阵推导🎰
- threejs系列: 物体详解🐧
- threejs系列: 材质与贴图详解🦥
- threejs系列: 曲线详解🥓
- threejs系列: 动画详解🧠
- …….
高强度持续更新,从0到1深入了解 threejs 的奥秘,喜欢的点个关注呀
矩阵
数学上,矩阵定义为是一个有m行(row)n列(column)元素的矩形阵列。在线性代数中矩阵和向量是随处可见的,向量与矩阵的计算也是该熟记的。
下面是一个3 * 3的矩阵。
⎩⎨⎧147258369⎭⎬⎫
矩阵加法
矩阵的加减法很简单,只需要把相对位置算数就可以,前提是矩阵的行列数相同。
{14}+{25}={1+24+5}={39} 矩阵乘法
矩阵乘以一个数字:
{14}∗4={1∗44∗4}={416} 矩阵与矩阵相乘:
前提:只有第一个矩阵的列的个数等于第二个矩阵的行的个数,这样的两个矩阵才能相乘。
A矩阵与B矩阵两个矩阵相乘得到的矩阵,会有矩阵A有相同的行数,会有矩阵B相同的列数。
例如:
2 * 3 矩阵 与 3 * 2 矩阵得到的就是一个 2 行 2 列的矩阵。
然后以分别进行 红蓝 、 红绿 、 橙蓝 、 橙绿组合进行点乘。
{adbfce}∗⎩⎨⎧hjlikm⎭⎬⎫={a∗h+b∗j+c∗ld∗h+f∗j+e∗la∗i+b∗k+c∗md∗i+f∗k+e∗m} 以上就是矩阵的简单计算。
向量
在上篇文章我们讲到的向量其实也能看作是一个m * 1的矩阵,比如:
向量[x,y,z]=⎩⎨⎧xyz⎭⎬⎫
在几何平面上:
oj为y坐标的单位向量,oi为x坐标的单位向量,oA可以表示为3oi+2oj
则矩阵表示的话是为:3{10}+2{01}={3∗1+2∗03∗0+2∗1}={32} =
计算方式和矩阵如出一辙{1001}{32}={3∗1+2∗03∗0+2∗1}={32} 这里由两个坐标系单位向量组成的矩阵也被称之为单位矩阵
{1001}
图中的 oj和oi 也被称为坐标系的基向量
旋转矩阵推导
将坐标轴逆时针旋转45°
oi由旋转公式可得:{cos45°sin45°},oj={−sin45°cos45°}
矩阵表示为:
{cos45°sin45°−sin45°cos45°}{32} 所以平面旋转矩阵为:
{cos45°sin45°−sin45°cos45°}
缩放矩阵推导
我们将坐标系缩小2倍
oi此时坐标:{1/z0},oj={01/z},又因为OA=3Oi+2Oj,所以矩阵表示为:{1/z001/z}{32} 缩放矩阵为:
{z00z}
线性变换
你会发现这种变换坐标系然后通过基向量获取点向量的方式很有趣,这种方式在数学中叫做线性变换
线性变换在几何直观上有如下特点:
- 变换前后,直线仍然保持是直线的状态
- 变换前后,原点保持固定,不会变化
平移矩阵推导
仿射变换
由于线性变换拥有原点固定的特点,所以无法进行平移,只能旋转和缩放。
一刻也无需为无法平移感伤,接下来出场的是 仿射变换
仿射变换与线性变换的最大不同就是原点可以移动。
通过添加一个维度进行线性变换然后在低纬度上投影,这样看上去就是在低纬度上移动了。
这张图形象的说明了仿射变换。
齐次坐标
齐次坐标就是将原先 n 维坐标改成 n + 1 维坐标表示。在3d图形学中,我们需要在向量中添加一个分量叫做 w ,表示在4维空间中的位置。物体的坐标其实是
(x/w, y/w ,z/w),因此当 w = 1 时,物体的xyz不会变化,所以通常我们都将 w 设置为1。
推导
我们回到平移推导,我们假设将坐标(x,y)平移到坐标(x’,y’),因为线性变换无法平移,所以我们需乘以一个未知的齐次平移矩阵
⎩⎨⎧xyz⎭⎬⎫∗⎩⎨⎧adgbehcf1⎭⎬⎫=⎩⎨⎧ax+by+czdx+ey+fzgx+hy+iz⎭⎬⎫ 得到以下等式
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。
将其带入后得到平移矩阵
⎩⎨⎧100010TxTy1⎭⎬⎫
至此,三个基础得几何转换矩阵都得出来了,这里不禁感叹道还真是不容易呢😅
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
我们来进行矩阵进行几何变换:
mesh.matrix.makeScale(0.5, 0.5, 0.5);
mesh.matrixAutoUpdate = false;
API就不一一讲了,都是易懂的。
原文链接:https://juejin.cn/post/7317827078114918427 作者:兰奇