第五章 三维观察
5.1 三维观察的流程
要获得三维世界坐标系场景的显示,必须先建立观察用的坐标系和“照相机”参数,该坐标系定义与观察平面或投影平面的方向。将对象描述转换到观察坐标系并投影到观察平面上,最后将所得的投影显示在终端设备的屏幕上。整个流程如图所示:
模型变换
模型变换是指在模型坐标系(局部坐标系)中构建的物体放到统一的世界坐标系(全局坐标系)的过程中,根据场景的需要所进行的组合变换。
其中模型坐标系是为了建模和模型调用变换的方便而构建的一个局部坐标系。一旦对多个物体进行了建模,下一步就是将其放置于我们希望的一个统一场景中。实质上就是将一个物体从模型坐标系到同一场景(世界坐标系)下的世界坐标。
观察变换
观察是指在世界坐标系中设定了观察坐标系后,物体中世界坐标系下世界坐标到观察坐标系下观察坐标的变换,这种变换也成为视点变换或试图变换。此时被观察对象在以镜头为原点的观察坐标系下就有了前后左右等未知的参考,即观察坐标。
观察坐标系也被称为视点坐标系,原点常常模拟为视点或摄像机的位置,z轴与观察方向共线。
投影变换
投影变换是指在观察坐标系设定投影平面后,将三维物体的观察坐标通过投影变换的方式变换为投影坐标系下投影坐标的过程,这一过程包含裁剪和投影两个过程。
1. 裁剪
由于最终成像结果不可能是无限大小,因此,三维观察和相机拍照一样,也需要一个取景框来选取要显示的对象。这个取景框就是观察窗口。对于三维观察来说,如果观察窗口是矩形,那么只有一个半无穷锥体内的对象才会被成像,这个半无穷锥体就是三位裁剪下的观察体。通常情况下,这个观察体以视点为参考点还会增加两个远平面作为远近裁剪平面,此时观察体就是一个四棱台,即截头锥体。
2. 投影
投影就是将观察体中的三位对象进行投影得到二维投影图。在投影时,先要设置一个观察平面,再将观察物体中三维对象投影到观察平面上,得到该对象的二维投影图。在计算机图形学中,投影有透视投影和平行投影两种。
视口变换
视口变换是指从投影坐标系中的观察窗口到设备坐标系中某个指定视区的变换。
视口变换的基本原理如图:

投影坐标系中的点(x_w,y_w)与设备坐标系下的点(x_v,y_v)相对应。由图中的比例关系,可以得到矩阵形式的变换公式:
\begin{bmatrix}x_v&y_v&1\end{bmatrix}=\begin{bmatrix}x_w&y_w&1\end{bmatrix}\begin{bmatrix}a&0&0\\0&-c&0\\b&d&1\end{bmatrix}
其中:
\begin{aligned}
&a=\frac{v xr-vxl}{wxr-wxl} \\
&b=vxl-\frac{vxr-vxl}{wxr-wxl}wxl \\
&c=\frac{vyt-vyb}{wyt-wyb} \\
&d=\frac{vyt-vyb}{wyt-wyb}wyb+vyt
\end{aligned}
5.2 观察变换
观察变换涉及两个坐标系,世界坐标系和观察坐标系。设世界坐标系为Oxyz,观察坐标系为O_vx_vy_vz_v。首先,在世界坐标系中选定一个点O_v做呗观察坐标系原点,称为视点。接着,从观察坐标系选取一点称为观察参考点,作为观察目标形成观察方向,将观察方向设定为z_v轴正向,在垂直于z_v轴方向上指定一个观察向上的向量\mathbf V为y_v轴正向,由此可以得到一个左手直角坐标系,即为观察坐标系O_vx_vy_vz_v,如图所示。

几何变换方法
如何求解能使点P在世界坐标系转换到观察坐标系的矩阵呢,有两种思路:
- 点P和观察坐标系不动,对世界坐标系进行几何变换,使其与观察坐标系重合。
- 世界坐标系不动,观察坐标系和P一起移动,使观察坐标系与世界坐标系重合。
这两种方法思路上本质一样,这里将会按照第一种方法的思路进行求解。这里假设观察坐标系下的观察点为O。
1. 原点到视点的平移变换
假设视点的坐标为(a,b,c),可以用球面坐标系表示。则O平移到O_v的变换矩阵为:
\boldsymbol{M}_1=\begin{bmatrix}1&0&0&-a\\0&1&0&-b\\0&0&1&-c\\0&0&0&1\end{bmatrix}=\begin{bmatrix}1&0&0&-R\sin\varphi\cos\theta\\0&1&0&-R\sin\varphi\sin\theta\\0&0&1&-R\cos\varphi\\0&0&0&1\end{bmatrix}
2. 绕z_1轴的旋转变换
将坐标系O_1x_1y_1z_1绕z_1轴顺时针旋转$90-\theta角,使y_1轴位于O_1O_pO$平面内。
\boldsymbol{M_2}=\begin{bmatrix}\cos\left(\frac{\pi}{2}-\theta\right)&-\sin\left(\frac{\pi}{2}-\theta\right)&0&0\\\sin\left(\frac{\pi}{2}-\theta\right)&\cos\left(\frac{\pi}{2}-\theta\right)&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}=\begin{bmatrix}\sin\theta&-\cos\theta&0&0\\\cos\theta&\sin\theta&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}
3. 绕x_2的旋转变换
将图中坐标系O_2x_2y_2z_2绕x_2轴作$180\degree - \phi$角的逆时针旋转变换。
\boldsymbol M_3=\begin{bmatrix}1&0&0&0\\0&\cos(\pi-\phi)&\sin(\pi-\phi)&0\\0&-\sin(\pi-\phi)&\cos(\pi-\phi)&0\\0&0&0&1\end{bmatrix}=\begin{bmatrix}1&0&0&0\\0&-\cos\phi&\sin\phi&0\\0&-\sin\phi&-\cos\phi&0\\0&0&0&1\end{bmatrix}
4. 关于y_3O_3z_3面的对称变换
由于世界坐标系是右手坐标系,观察坐标系是左手坐标系,两者还需要通过一次对称变换才能完全重合。
\boldsymbol{M}_4=\begin{bmatrix}-1&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}
5. 综合变换矩阵
M=M_4M_3M_2M_1
计算后得:
\boldsymbol{M}=\begin{bmatrix}-\sin\theta&\cos\theta&0&0\\-\cos\varphi\cos\theta&-\cos\varphi\sin\theta&\sin\varphi&0\\-\sin\varphi\cos\theta&-\sin\varphi\sin\theta&-\cos\varphi&R\\0&0&0&1\end{bmatrix}
那么求得物体在观察坐标系下的变换坐标为:
\begin{bmatrix}x'\\y'\\z'\\1\end{bmatrix}=M\begin{bmatrix}x\\y\\z\\1\end{bmatrix}
基变换也是一种简单的变换方法,由于需要必要的线性代数知识,这里不再阐述。
5.3 投影变换
投影的分类
根据投影中心与投影oymm之间距离的不同,可以分为平行投影和透视投影。平行投影的投影中心与投影平面的距离为无限大。透视投影的距离是有限的。
投影的具体分类如下图所示:
平行投影
根据投影方向和投影平面的夹角不同,平行投影可分成两类:正投影和斜投影。正投影的一个直接的例子就是三视图。
三视图
三视图包含主视图、侧视图和俯视图3个方向视图,观察平面分别与x轴、y轴和z轴垂直。三视图的绘制步骤如下:
- 确定三维物体上的各点的坐标;
- 引入齐次坐标,使用列向量表示;
- 将所作变换用矩阵表示,通过矩阵运算求得三维物体上各点(x,y,z)经变换后相应的点(x',y',z')$,并转换为投影后的二维点坐标。
- 由变换后的所有二维点绘出三维物体投影后的三视图。
主视图是将三维物体向xOz面做垂直投影得到主视图,其变换矩阵为:
\boldsymbol{T}_{V}=\begin{bmatrix}1&0&0&0\\0&0&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}
俯视图就是将三维物体向xOy面做垂直投影,为了将俯视图和主视图放在一个平面,需要将其沿x轴逆时针旋转$90\degree,再沿z轴的负方向平移一段距离z_0$,以防两个图形重叠。其变换矩阵为:
\begin{aligned}
\boldsymbol{T}_H&=\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&1&-z_0\\0&0&0&1\end{bmatrix}\begin{bmatrix}1&0&0&0\\0&\cos\bigl(-\frac\pi2\bigr)&-\sin\bigl(-\frac\pi2\bigr)&0\\0&\sin\bigl(-\frac\pi2\bigr)&\cos\bigl(-\frac\pi2\bigr)&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&0&0\\0&0&0&1\end{bmatrix}\\
&=\begin{bmatrix}1&0&0&0\\0&0&0&0\\0&-1&0&-z_{0}\\0&0&0&1\end{bmatrix}
\end{aligned}
侧视图将三维物体向yOz面作垂直投影,得到侧视图。为了将侧视图在xOz面上画出,需要将投影面绕z轴顺时针旋转$90\degree$,其变换矩阵为:
\begin{aligned}
\boldsymbol{T}_W&=\begin{bmatrix}1&0&0&-x_0\\0&1&0&0\\0&0&1&-z_0\\0&0&0&1\end{bmatrix}\begin{bmatrix}\cos(\frac{\pi}{2})&-\sin(\frac{\pi}{2})&0&0\\\sin(\frac{\pi}{2})&\cos(\frac{\pi}{2})&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}0&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}\\
&=\begin{bmatrix}0&-1&0&-x_0\\0&0&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}
\end{aligned}
正轴侧视图
显示对象的多个侧面的正投影可以使用正轴测视图,当观察平面与三个坐标轴之间的夹角都相等时为正等测,当观察平面与两个坐标轴之间的夹角都相等时为正二测,当观察平面与三个坐标轴之间的夹角都不相等时用称为正三测。为了绘制正轴测投影视图,一般先将三维实体分别绕两个坐标轴旋转一定的角度,然后再由这两个坐标轴所决定的坐标平面作正投影。一种常用的方法如下:
- 先将三维实体绕z轴逆时针旋转\alpha角。
- 再将三维实体绕x轴顺时针旋转\beta角。
- 向xOz平面做正投影。
其变换矩阵为:
\begin{aligned}
\text{T}& =\begin{bmatrix}1&0&0&0\\0&0&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}1&0&0&0\\0&\cos\beta&\sin\beta&0\\0&-\sin\beta&\cos\beta&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}\cos\alpha&-\sin\alpha&0&0\\\sin\alpha&\cos\alpha&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix} \\
&=\begin{bmatrix}\cos\alpha&-\sin\alpha&0&0\\0&0&0&0\\-\sin\alpha\sin\beta&-\cos\alpha\sin\beta&\cos\beta&0\\0&0&0&1\end{bmatrix}
\end{aligned}
在轴测投影中,沿三坐标向直线的投影长度与实际长度之比称为轴向变形系数或轴向变化率,分别用\eta_x、\eta_y、\eta_z表示。
- 当\eta_x\neq\eta_y\neq\eta_z时,为正三测;
- 当任意两个变形系数相等时,为正二侧;
- 当\eta_x=\eta_y=\eta_z时,为正等测。
按照上面的变形矩阵来看,三个轴向变形系数的计算公式分别为:
\begin{aligned}&\eta_x=OA^{\prime}/OA=\sqrt{\cos^2\alpha+\sin^2\alpha\sin^2\beta}\\&\eta_y=OB^{\prime}/OB=\sqrt{\sin^2\alpha+\cos^2\alpha\sin^2\beta}\\&\eta_z=OC^{\prime}/OC=\cos\beta\end{aligned}
由此可以得出正等测的角度为:\alpha=45\degree、\beta=35\degree16^\prime。其余视图计算同理。
斜投影
投影路径和观察平面不垂直时,称该映射为斜平行投影,简称为斜投影。常用的斜投影有斜等测和斜二测。
在斜投影中,常用两个角度\alpha和\varphi描述。\alpha是斜投影线和投影面的夹角。假设点P(x,y,z)在投影平面的正投影点为O(x,y,z_{vp}),斜投影点为P'(x_p,y_p,z_p)。角\varphi为投影oymmde水平方向夹角与PP'的夹角。
假设OP'长度为L,可以得到x_p,y_p的计算公式:
\begin{cases}x_p=x+L\cos\varphi\\y_p=y+L\sin\varphi\end{cases}
已知\tan\alpha=\frac{z_{vp}-z}{L},记L_1= \ctg{\alpha},得到:
\begin{cases}x_p=x+L_1(z_{vp}-z)\cos\varphi\\y_p=y+L_1(z_{vp}-z)\sin\varphi\end{cases}
上述公式就是斜投影的计算公式。
角度\varphi经常使用$30\degree和$40\degree,当投影角\tan\alpha = 2时,生成的视图为斜二测投影图,\tan\alpha = 1时,生成的视图为斜等测投影图。
透视投影
与平行投影相比,透视投影的特点就是所有的投影线都从空间一点投射,离视点近的物体投影大,离视点远的物体投影小,小到极点称为灭点。我们平常用照相机拍摄的照片都是透视投影的例子。
点的透视
为了方便起见,我们需要将已经变换好的观察坐标系变换成投影坐标系。变换十分简单,只需将观察坐标系沿z轴向其负方向平移距离d即可。其中视点为E(0,0,d),设空间任意一点为P(x,y,z),视线EP和投影面的交点为P'。
已知视线EP的直线参数方程为:
\begin{cases}X=0+(x-0)t\\Y=0+(y-0)t\\Z=d+(z-d)t\end{cases}
令Z=0,即可得出P'的坐标:
\begin{cases}x'=xd/(d-z)\\y'=yd/(d-z)\\z'=0\end{cases}
为了之后能够进行隐藏面消除,我们需要保留P'的深度信息,在实际应用中,我们需要在投影点后面增加一个伪深度值,从而实现消隐。考虑到伪深度值与z的线性关系表达式,的一致性,可以采用如下方式保留P'的伪深度信息:
\begin{cases}x'=x/\left(1-\dfrac{z}{d}\right)\\y'=y/\left(1-\dfrac{z}{d}\right)\\z'=z/\left(1-\dfrac{z}{d}\right)\end{cases}
用齐次坐标写成矩阵形式,如下:
\begin{bmatrix}x^{\prime}\\y^{\prime}\\z^{\prime}\\1\end{bmatrix}=\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&-\frac{1}{d}&1\end{bmatrix}\begin{bmatrix}x\\y\\z\\1\end{bmatrix}
此时再对P'进行正投影变换,就能得到投影面上的坐标值。
由透视变换公式可以得到,当P点距离视点越来越远的时候,P'点之间趋向(0,0,-d)。
直线的透视
设一直线过点P_0(x_0,y_0,z_0),方向向量为c(c_x,c_y,c_z)。其直线的点参式为P(t)=P_0+ct。将点参式带入点的透视变换公式,可得到经过透视变换的直线的参数方程:
\begin{cases}x'=(x_0+c_xt)/\left(1-\frac{z_0+c_zt}{d}\right)\\y'=(y_0+c_yt)/\left(1-\frac{z_0+c_zt}{d}\right)\\z'=(z_0+c_zt)/\left(1-\frac{z_0+c_zt}{d}\right)\end{cases}
通过上面的参数方程我们可以得出以下性质:
- 平行于画面的直线,其透视仍平行于画面,其透视投影和该直线和该直线的投影相互平行。其平行于画面的两条平行线,其透视和透视投影也相互平行。
- 垂直于画面的直线,其透视会于一点(0,0,-d)。
- 与画面相交的直线,其透视及透视投影必各有一个灭点,其透视灭点为(-dc_x/c_z,-dc_y/c_z,-d)。
- 过视点的直线,其透视投影只有一点(-dx_x/c_z,-dc_y/c_z,0)。
体的透视
透视投影中主灭点的数目来分为三种透视:一点透视、两点透视和三点透视。
一点透视:世界坐标系某一个主轴垂直于画面。
两点透视:世界坐标系某一主轴平行于画面,另两条主轴相交。
三点透视:世界坐标系三条主轴均与画面相交。
5.4 观察体及其规范化
在计算机处理投影的过程中,常用到观察体来描述摄像机摄入物体的多少。在之前我们介绍了近平面和远平面的概念,这在观察体中也经常遇到。
正投影下的观察体和规范化
正投影的观察体是一个标准的长方体,其前后两个面由近平面和远平面组成。观察体内的物体是我们观察到的,其余的所有物体都会被裁剪掉。
为了保证不同输出设备有统一的观察体输出形式,一般需要对观察体进行规范化变换。将观察体的坐标系规范成0~1。不同的坐标系规范化会将其规范成-1~1。由于屏幕坐标经常指定为左手系,因此规范化观察体也常指定为左手坐标系统。
将位置(xw_{\max},yw_{\max},z_\text{far})映射到(1,1,1)。将(xw_{\min},yw_{\min},z_\text{near})映射到(-1,-1,-1)。其投影矩阵如下:
\boldsymbol{M}_{\mathrm{ortho,~nom}}=\begin{bmatrix}\frac{2}{xw_{\max}-xw_{\min}}&0&0&-\frac{xw_{\mathrm{max}}+xw_{\mathrm{min}}}{xw_{\mathrm{max}}-xw_{\mathrm{min}}}\\0&\frac2{yw_{\max}-yw_{\min}}&0&-\frac{yw_{\max}+yw_{\min}}{yw_{\max}-yw_{\min}}\\0&0&\frac{-2}{z_\mathrm{near}-z_\mathrm{far}}&\frac{z_\mathrm{near}+z_\mathrm{far}}{z_\mathrm{near}-z_\mathrm{far}}\\0&0&0&1\end{bmatrix}
将该矩阵的左边与组合观察变换\mathbf{RT}相乘,就能得到从世界坐标系到规范化正投影坐标系的转换。
斜投影下的观察体及规范化
斜投影一般指的是z轴的正切变换,用投影向量\boldsymbol{V}_p=(\boldsymbol{V}_{px},\boldsymbol{V}_{py},\boldsymbol{V}_{pz})来表示,如图所示:
斜投影的观察体先经过一些变换转别为正投影位置,然后使用正投影的规范化过程,斜投影转化为正投影的变换矩阵为:
\boldsymbol{M}_{\mathrm{oblique}}=\begin{bmatrix}1&0&-\dfrac{V_{px}}{V_{pz}}&z_{vp}\dfrac{V_{px}}{V_{pz}}\\&&V_{pv}&V_{pv}\\0&1&-\dfrac{V_{py}}{V_{pz}}&z_{vp}\dfrac{V_{pz}}{V_{pz}}\\0&0&1&0\\0&0&0&1\end{bmatrix}
透视投影下的观察体可视化
在透视变换规范化前,需要定义几个参数,如图所示:
首先现将投影坐标系沿z轴平移n,此时z=-n变为z'=0,z=-f变为z'=-f+n。其相应的变换矩阵为:
\boldsymbol{T_1} = \begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&1&n\\0&0&0&1\end{bmatrix}
然后对观察体进行透视变换,视点位置为(0,0,n),变换矩阵为:
\boldsymbol{T_2}=\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&-\dfrac{1}{n}&1\end{bmatrix}
变换后的观察体为一个长方体,近裁剪面z=0保持不变,远裁剪面z=n-f变为z'=n(n-f)/f。
首先将长方体的z坐标变换到-1\sim1。变换矩阵为:
\boldsymbol{T}_3=
\begin{bmatrix}1&{0}&0&{0}\\{0}&1&0&0\\0&0&\frac{2f}{n(n-f)}&-1\\0&0&0&1\end{bmatrix}
至于x方向和y方向,先将长方体在x方向上平移-(l+r)/2,在y方向上平移-(b+t)/2,使得裁剪窗口端面中心与原点重合。其变换矩阵为:
\boldsymbol{T}_4=\begin{bmatrix}1&0&0&-(l+r)/2\\0&1&0&-(b+t)/2\\0&0&1&0\\0&0&0&1\end{bmatrix}
然后在x方向上缩放 2/(r-l),y方向上缩放2/(t-b),其变换矩阵为:
\boldsymbol{T}_5=\begin{bmatrix}2/(r-l)&0&0&0\\0&2/(t-b)&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix}
经过上述所有变换就得到了最终的投影变换:
\left.\boldsymbol{T}_{5}\boldsymbol{T}_{4}\boldsymbol{T}_{3}\boldsymbol{T}_{2}\boldsymbol{T}_1
\boldsymbol{P}=\boldsymbol{T}\boldsymbol{P}=\left[\begin{matrix}{\frac{2}{(r-l)}}&{0}&{\frac{r+l}{n(r-l)}}&{0}\\{0}&{\frac{2}{(t-b)}}&{\frac{t+b}{n(t-b)}}&{0}\\{0}&{0}&{\frac{n+f}{n(n-f)}}&{\frac{2f}{n-f}}\\{0}&{0}&{-\frac{1}{n}}&{0}\\\end{matrix}\right.\right]
评论区