计算机图形学的几何变换

参考资料:Real-Time Rendering

仿射变换

  • 关于仿射变换群,可参见矩阵群
  • \mathbb{R}^3上的仿射变换,是仿射变换群\mathbb{R}^3 \rtimes GL(3, \mathbb{R})中的元素

        \[ f(x) = Ax + b,\; A \in GL(3, \mathbb{R}),\; b \in \mathbb{R}^3. \]

  • \mathbb{R}^3上的仿射变换,也是\mathbb{R}P^3上保持无穷远超平面H_\infty的射影变换

        \[ f\bigg(\begin{bmatrix}x \\ 1\end{bmatrix}\bigg) = \begin{bmatrix}A & b \\ 0 & 1\end{bmatrix}\begin{bmatrix}x \\ 1\end{bmatrix} = \begin{bmatrix}Ax + b \\ 1\end{bmatrix},\; \begin{bmatrix}x \\ 1\end{bmatrix} \in \mathbb{R}^3, \]

        \[ f\bigg(\begin{bmatrix}x \\ 0\end{bmatrix}\bigg) = \begin{bmatrix}A & b \\ 0 & 1\end{bmatrix}\begin{bmatrix}x \\ 0\end{bmatrix} = \begin{bmatrix}Ax \\ 0\end{bmatrix},\; \begin{bmatrix}x \\ 0\end{bmatrix} \in H_\infty. \]

  • \mathbb{R}P^3是3维实射影空间

        \[ \mathbb{R}P^3 = (\mathbb{R}^4 - \{ 0 \})/\sim, \text{ where } v \sim \lambda v \text{ for any } \lambda \neq 0. \]

    也就是说,\mathbb{R}P^3可以用4维坐标来表示(不能为原点),其中相差非零常数倍的坐标是等价的。\mathbb{R}P^3中的点是一个等价类,即\mathbb{R}^4中通过原点的直线;记最后一个坐标为1的平面为H,那么这些直线可以分为2类
    • 一类是直线与H相交,得到\mathbb{R}^3中的点。上面的第一类公式即为\mathbb{R}^3中的点的仿射变换
    • 另一类是直线与H平行,得到H_\infty中的点。由平行性,它也可以视为\mathbb{R}^3中的向量,上面的第二类公式即为\mathbb{R}^3中的向量的仿射变换
    • 进一步,\mathbb{R}P^3上的射影变换构成射影变换群

          \[ PGL(4, \mathbb{R}) = GL(4, \mathbb{R})/\sim, \text{ where } A \sim \lambda A\text{ for any } \lambda \neq 0. \]

      也就是说,射影变换可以由A \in GL(4, \mathbb{R})诱导,

          \[ [A]: \mathbb{R}P^3 \to \mathbb{R}P^3,\; [v] \mapsto [Av]. \]

  • 从线性方程出发中的Gauss消元法可知,GL(3, \mathbb{R})可以由初等变换生成。因此,\mathbb{R}^3上的仿射变换可以由平移、初等变换生成,这些初等变换都有几何意义
    • 平移(Translation)

          \[ \begin{bmatrix}1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1\end{bmatrix}. \]

    • 伸缩(Scaling)

          \[ \begin{bmatrix}s & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1\end{bmatrix}. \]

    • 切变(Shearing)

          \[ \begin{bmatrix}1 & s & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1\end{bmatrix}. \]

    • 镜面反射(Mirror Reflection)

          \[ \begin{bmatrix}0 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1\end{bmatrix}. \]

刚体变换

  • 关于刚体变换群,可参见矩阵群
  • \mathbb{R}^3赋予典范Riemann度量,成为一个Riemann流形

        \[ g_{can}(v, w) = v_1w_1 + v_2w_2 + v_3w_3. \]

    \mathbb{R}^3上的刚体变换,是保持定向的等距变换群Isom^+(\mathbb{R}^3, g_{can})中的元素
    • 一方面,刚体变换群满足

          \[ SE(3, \mathbb{R}) = \mathbb{R}^3 \rtimes SO(3, \mathbb{R}) \subset Isom^+(\mathbb{R}^3, g_{can}). \]

    • 另一方面,由Riemann几何的结果可知,f \in Isom^+(\mathbb{R}^3, g_{can})可以由其1阶展开确定,

          \[ f(x) = f(0) + df_0 \cdot x,\; df_0 \in SO(3, \mathbb{R}). \]

      从而,f \in SE(3, \mathbb{R})。因此,\mathbb{R}^3上的刚体变换,也是刚体变换群SE(3, \mathbb{R})中的元素
  • SO(3, \mathbb{R})中的元素都是绕某条直线的旋转(Rotation),从而\mathbb{R}^3上的刚体变换可以由平移、绕某条直线的旋转生成
    • A \in SO(3, \mathbb{R})。那么,

          \[ \det(A - I) = \det(A^T(A - I)) = \det(I - A^T) = (-1)^3\det(A - I), \]

      \det(A - I) = 0。因此,线性方程AX = X存在非零解X_0,从而A保持X_0方向的直线L不变
    • 同时,A在与L正交的2维平面上,也是保持定向的等距变换,并且保持原点不变,所以是SO(2, \mathbb{R})中的元素。由四元数可知,SO(2, \mathbb{R})中的元素是绕原点的旋转,所以A是绕直线L的旋转
  • 数值线性代数中的奇异值分解可知,GL(3, \mathbb{R})可以由对角元素为正的对角矩阵、O(3, \mathbb{R})生成。由矩阵群可知,O(3, \mathbb{R})可以由SO(3, \mathbb{R})、一个行列式为-1的矩阵生成
    • 对角元素为正的对角矩阵 –> 对角元素为正的伸缩
    • O(3, \mathbb{R}) –> 旋转、镜面反射
  • 因此,我们也可以将上面的伸缩更换为对角元素为正的伸缩,将上面的切变更换为旋转。在计算机图形学中,旋转通常用四元数来表示

四元数和旋转

  • 关于四元数,可参见四元数
  • 四元数的集合\mathbb{H}可以视为\mathbb{R}^4,并且可以分解为实部(基底为1,可以视为\mathbb{R})、虚部(基底为ijk,可以视为\mathbb{R}^3)。只有实部的四元数为实数,只有虚部的四元数为纯虚数
  • q为四元数,|q| = 1。定义

        \[ f_q: \mathbb{H} \to \mathbb{H}, x \mapsto qxq^{-1}. \]

    那么,f_q\mathbb{R}-线性变换,并且保持1不变,从而保持实数不变。因此,我们只需考虑纯虚数的情形,并且将f_q视为\mathbb{R}^3上的\mathbb{R}-线性变换
  • 模长为1的纯虚数具有良好的性质。设uv为模长为1的纯虚数,那么

        \[ u^{-1} = \overline{u} = -u,\; v^{-1} = \overline{v} = -v,\; u^2 = v^2 = -1. \]

    同时,

        \begin{equation*}\begin{split} uv &= (u_xi + u_yj + u_zk)(v_xi + v_yj + v_zk) \\ &= (-u \cdot v, u \times v). \end{split}\end{equation*}

    在最后一步,我们将uv视为\mathbb{R}^4中的向量,将uv视为\mathbb{R}^3中的向量。因此,模长为1的纯虚数的乘法,实部相当于向量的内积,虚部相当于向量的外积
  • q分解为实部、虚部,

        \[ q = \cos(\phi) + \sin(\phi)u,\; q^{-1} = \overline{q} = \cos(\phi) - \sin(\phi)u, \]

    其中,u为模长为1的纯虚数。计算

        \begin{equation*}\begin{split} f_q(x) &= qxq^{-1} \\ &= (\cos(\phi) + \sin(\phi)u)x(\cos(\phi) - \sin(\phi)u) \\ &= \cos^2(\phi)x - \sin^2(\phi)uxu + \sin(\phi)\cos(\phi)(ux - xu). \end{split}\end{equation*}

    • u^2 = -1可知,f_q保持u不变,从而保持u方向的直线L不变
    • 同时,在与L正交的2维平面上,任取一个模长为1的纯虚数v。利用u \cdot v = 0,可得uv = (0, u \times v),它也是模长为1的纯虚数,并且对应于u \times v。由此可知,uvuv构成右手坐标系,并且uv = -vu。因此,f_q(v) = \cos(2\phi)v + \sin(2\phi)uvv绕直线L旋转2\phi

计算机图形学的MVP变换

  • 计算机图形学可以将\mathbb{R}^3中的模型渲染为\mathbb{R}^2中的图像,其原理类似于相机拍摄模型的照片
  • 模型(Model)变换是一个仿射变换(模型 –> M –> 世界空间)
    • 模型变换可以让我们将模型设置为合适的位置(平移)、合适的大小(伸缩)、合适的角度(旋转)
  • 视觉(View)变换是一个仿射变换(世界空间 –> V –> 视觉空间)
    • 视觉变换可以让我们获得在相机的位置和角度,人眼所见的原风景
    • 设相机的位置(Eye)为e,相机对准的方向(Gaze)为g,相机朝上的方向(Top)为t。首先,我们使用一个平移,将相机的位置变为原点

          \[ \begin{bmatrix}1 & 0 & 0 & -e_x \\ 0 & 1 & 0 & -e_y \\ 0 & 0 & 1 & -e_z \\ 0 & 0 & 0 & 1\end{bmatrix}\begin{bmatrix}e_x \\ e_y \\ e_z \\ 1\end{bmatrix} = \begin{bmatrix}0 \\ 0 \\ 0 \\ 1\end{bmatrix}. \]

    • 其次,我们使用一个旋转,将g变为-z轴,将t变为y轴,将r = g \times t变为x轴。之所以取-z轴,是因为在右手坐标系中,如果人眼所见为x轴水平向右、y轴垂直向上,那么-z轴的方向是人眼所见的方向

          \[ \begin{bmatrix}r_x & r_y & r_z & 0 \\ t_x & t_y & t_z & 0 \\ -g_x & -g_y & -g_z & 0 \\ 0 & 0 & 0 & 1\end{bmatrix}\begin{bmatrix}r_x & t_x & g_x \\ r_y & t_y & g_y \\ r_z & t_z & g_z \\ 0 & 0 & 0\end{bmatrix} = \begin{bmatrix}1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & -1 \\ 0 & 0 & 0\end{bmatrix}. \]

  • 投影(Projection)变换是一个射影变换(视觉空间 –> P –> 照片)
    • 投影变换可以让我们从3维降低到2维
    • 在相机拍摄模型的照片时,人眼所见的原风景并不是整个\mathbb{R}^3,而是一个有限的视觉体积(View Volume)。根据透视原理,我们可以取视觉体积为从原点出发的锥体
    • 因为我们拍摄的照片通常是矩形的,所以我们让锥体的底面为矩形。因为视觉体积有限,所以我们用一个较远的平面来截断锥体,得到远底面;因为人眼位于原点,所以我们取一个较近的平面作为照片,得到近底面,然后投影到其上
    • 设近底面、远底面的z坐标分别为0 > n > f。对于近底面n、远底面f之间的所有模型上的点(x, y, z),我们都使用透视将其投影到近底面n上,x \mapsto \frac nzxy \mapsto \frac nzy。这无法用仿射变换来实现,原因是z坐标是变量,故我们使用射影变换

          \[ \begin{bmatrix}n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ * & * & * & * \\ 0 & 0 & 1 & 0\end{bmatrix}\begin{bmatrix}x \\ y \\ z \\ 1 \end{bmatrix} = \begin{bmatrix}nx \\ ny \\ * \\ z \end{bmatrix} \sim \begin{bmatrix}\frac{nx}{z} \\ \frac{ny}{z} \\ * \\ 1 \end{bmatrix}. \]

      (x, y)坐标而忽略z坐标,即可得到想要的照片
  • 因为近的模型会挡住远的模型,所以z坐标用于判断模型的远近
    • 如果我们让射影变换保持近底面n、远底面f不变,并且z坐标与(x, y)坐标无关,那么我们可以得到完整的射影变换

          \[ \begin{bmatrix}n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n + f & -nf \\ 0 & 0 & 1 & 0\end{bmatrix}\begin{bmatrix}x \\ y \\ z \\ 1 \end{bmatrix} = \begin{bmatrix}nx \\ ny \\ (n + f)z - nf \\ z \end{bmatrix} \sim \begin{bmatrix}\frac{nx}{z} \\ \frac{ny}{z} \\ n + f - \frac{nf}{z} \\ 1 \end{bmatrix}. \]

      并非所有模型上的(x, y)坐标都会出现在照片上,只有对应的z坐标距离原点最近才行(由于0 > n > z > f,这需要z最大)