https://www.bilibili.com/read/cv200169/
0x00 前言
嗨,你说表示一个三维的点,我们需要几个数字来表达?学过小学数学的你一定知道,表达一个三维的点用3个数字足够表达他的位置了,比如P1(X1,Y1,Z1)这三个坐标分别表达了这个点在坐标系中X轴,Y轴,Z轴的距离,3个数字足够表达一个三维的点了。也就是说(X1,Y1,Z1)这个矩阵表达了P1这个点的位置。但是,为啥图形学这么不讨好的需要4x4的矩阵呢?
0x01 旋转
按照这个随意作的图,我们可以看出来顶点P1绕Z轴旋转了β度来到了P2。那么,我们这里设P1的模为L。因为是按照Z轴进行旋转,我们就不关注Z轴了。对此我们可以得到:
X1=L·sinα
Y1=L·cosα
哪样我们也可以得到:
X2=L·sin(α+β)
Y2=L·cos(α+β)
对此我们将三角函数展开,可以得到
X2=L·(sinαcosβ+cosαsinβ)= cosβ·X1+sinβ·X1
Y2=L·(sinαcosβ-cosαsinβ) = cosβ·Y1-sinβ·X1
所以,我们就可以得到P2这个点的坐标
X2=L·(sinαcosβ+cosαsinβ)= cosβ·X1+sinβ·X1
Y2=L·(sinαcosβ-cosαsinβ) = cosβ·Y1-sinβ·X1
Z2=Z1
到这里似乎都不错,也没啥大问题,我们来试试看3X3的矩阵来做这个旋转
| X2 | | a b c | | X1 |
| Y2 | = | d e f | | Y1 |
| Z2 | |g h i | | Z1 |
说白了也就是
X2=aX1+bX1+cX1
Y2=dY1+eY1+fY1
Z2=gZ1+hZ1+iZ1
对比上下两个方程,我们不难发现
a=cosβ b=sinβ c=0
d=-sinβ e=cosβ f=0
g=0 h=0 i=0
代入矩阵,我们可以得到
| X2 | | cosβ sinβ 0 | | X1 |
| Y2 | = | -sinβ cosβ 0 | | Y1 |
| Z2 | |0 0 0 | | Z1 |
这也就是说,使用3x3的矩阵就可以搞定三维中的顶点旋转了!所以,我们根本不需要4x4的矩阵吧!
0x02 问题出现在位移

我们可以知道从P1到P2的位移可以写成
X2=X1+ΔX
Y2=Y2+ΔY
Z2=Z2+ΔZ
那我们继续对照矩阵变化来试试看
X2=aX1+bX1+cX1 X2=X1+ΔX
Y2=dY1+eY1+fY1 Y2=Y2+ΔY
Z2=gZ1+hZ1+iZ1 Z2=Z2+ΔZ
看起来不对劲啊,我们没办法找到ΔX,ΔY,ΔZ这三个变量对应的变量。
0x03 试试看4X4的矩阵
那看来没办法用3X3的矩阵来解决三维点的位移啊。那我们不妨试试看4X4的矩阵吧!这样我们就将原来(x,y,z)改成了(x,y,z,w)这样的四维向量,这第四个分量我们称为齐次坐标。它等价于(x/w,y/w,z/w)。这样也就是说,当第四分量是1的时候,这个坐标就可以当作三维坐标来使用,x,y,z也正好代表这3个值为值的坐标点。如此,我们为了和4x4的矩阵相乘,就变成了(x1,y1,z1,w)
那么矩阵等式就可以变为
|X2| | a b c d | | X1 |
|Y2| | e f g h | | Y1 |
|Z2| = | i j k l | | Z1 |
|1 | |m n o p| | 1 |
这样,我们的等式就可以成立了,更重要的是,我们的矩阵可以支持顶点的旋转和位移!
0x04 最后的话
当然也不是所有的时候都需要4X4的矩阵来进行变换。就比如我们进行仿射变换的时候只需要3X3的矩阵和平移矢量。但是我们要是需要透视投影的时候,齐次坐标是个非常有用的矩阵。(此文章为本人制作MMD中fx编程的引子)