OpenGL ES 的很多教程里都会有这样一个例子来讲解纹理:将一张图片作为纹理显示在屏幕上。
因为纹理坐标和实际屏幕显示的坐标不一样,把图片渲染在屏幕上后,图片是上下颠倒的。
一个解决方法是对当前的顶点坐标,乘以绕 z 轴旋转180度的矩阵,这样图片就能正确显示了。
$$
\begin{bmatrix}
cos\theta & -sin\theta & 0 & 0 \\ sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \
\end{bmatrix}
$$
那么如何理解这个旋转矩阵呢?
影响我们理解这个矩阵的第一个问题是:
为什么这个矩阵是 4x4 的?
而且我们发现旋转,缩放、平移等变换矩阵都是 4x4 的。
在直观上的认知里,表达一个三维空间的坐标用 x,y,z 就足够了,那在三维空间里进行矩阵变换,用 3x3 的矩阵就够了,为什么需要 4x4 呢?
为了回答这个问题,下面我们先在几何意义上理解
向量和矩阵
之间的关系,然后通过
推导旋转矩阵
和
平移矩阵
,一步步来解开这个疑惑。
向量空间
(包括由函数构成的抽象的向量空间)之间的一种保持向量加法和标量乘法的特殊映射
线性变换在几何直观上有如下特点:
变换前后,直线仍然保持是直线的状态
变换前后,原点保持固定,不会变化
我们从二维平面,推导到三维坐标也是同理,只不过是多了个 z 轴
$$
\begin{bmatrix}
1 & 0 & 0 \\0 & 1 & 0 \\0 & 0 & 1
\end{bmatrix}
$$
竖着来看这个矩阵,是 x,y,z轴上的三个基向量,同时它又是一个单元矩阵。
同理上面二维平面的推导,三维坐标绕 z 轴的旋转矩阵为:
$$
\begin{bmatrix}
cos\theta&-sin\theta&0\\sin\theta&cos\theta&0\\0&0&1
\end{bmatrix}
$$
线性变换
并接上一个平移,变换为另一个向量空间。
仿射变换在几何直观上,相比线性变换,它不需要保证变换前后坐标原点不变。
如下图,从 A 点平移到 B 点,我们换一个角度思考,这次不移动点,而是
移动整个坐标轴
,同样可以达到平移 A 点到 B 点的需求,但是坐标原点移动到了 O’ 点(1,3)。
我们希望构造的是像下面这种矩阵乘法的等式,这样才能用一个通用的计算模式来处理坐标点的变换。
$$
\begin{bmatrix}
矩阵
\end{bmatrix}
\begin{bmatrix}
3\\2
\end{bmatrix}
=
\begin{bmatrix}
4\\5
\end{bmatrix}
$$
到这里,我们终于要请出
齐次坐标
了。
齐次坐标就是将一个原本是 n 维的向量用一个 n+1 维向量来表示,是指一个用于投影几何里的坐标系统,如同用于欧氏几何里的笛卡儿坐标一般。
用一个通俗的讲法是,我们需要
升维
来处理这个问题。
通过增加一个维度,我们可以在
高维度
上,通过线性变换来处理
低维度
的仿射变换。
这句话咋一听感觉很有哲理,但是通过下面的数学等式就能知道其中的奥妙:
$$
\begin{bmatrix}
1 & 0 & 1 \\0 & 1 & 3 \\0 & 0 & 1
\end{bmatrix}
\begin{bmatrix}
3 \\ 2 \\ 1
\end{bmatrix}
=
\begin{bmatrix}
1 \times 3 + 0 \times 2 + 1 \times 1 \\0 \times 3 + 1 \times 2 + 3 \times 1 \\0 \times 3 + 0 \times 2 + 1 \times 1
\end{bmatrix}
=
\begin{bmatrix}
4 \\ 5 \\ 1
\end{bmatrix}
$$
观察上面的运算过程,结果 $\begin{bmatrix}4\\5\\1 \end{bmatrix}$ 不正是我们上面所得的 $\begin{bmatrix} 4\\5 \end{bmatrix}$ 吗?只不过多了一个 z 轴的坐标值。
我们通过升级一个维度,将在二维平面上的平移问题转换成了在三维坐标的矩阵和向量乘法。那么在二维平面上,这个平移矩阵就为:
$$
\begin{bmatrix}
1 & 0 & tx \\0 & 1 & ty \\0 & 0 & 1
\end{bmatrix}
$$
tx 和 ty 就对应在 x 轴 和 y 轴上的移动距离。
同理推广到三维坐标系,要实现三维坐标的平移操作,同样需要通过升维,引入齐次坐标来计算。那么三维坐标下的平移矩阵就为:
$$
\begin{bmatrix}
1 & 0 & 0 & tx \\0 & 1 & 0 & ty \\0 & 0 & 1 & tz \\0 & 0 & 0 & 1 \
\end{bmatrix}
$$