三维投影

三维投影是将三维空间中的点映射到二维平面上的方法。由于目前绝大多数图形数据的显示方式仍是二维的，因此三维投影的应用相当广泛，尤其是在计算机图形学，工程学和工程制图中。

## 分类

- 三维图形平面投影
- 平行投影：投影中心与投影平面的距离是无限的，投影线相互平行
- 正投影（正交投影）：投影线垂直于投影平面
- 多视图投影：物体的坐标面与投影面平行，正视图、侧视图、俯视图
- 轴测投影：物体的三个坐标面或坐标轴与投影面均不平行
- 正等轴测投影（正等测）：投影时三个坐标轴等比例缩放，投影面坐标轴夹角120°
- 正二轴测投影（正二测）：投影时两个坐标轴等比例缩放，第三个坐标轴缩放比例不同
- 正三轴测投影（正三测）：投影时三个坐标轴缩放比例均不相等
- 斜投影：投影线不垂直于投影平面
- 斜等轴测投影（斜等测）
- 斜二轴测投影（斜二测）
- 斜三轴测投影（斜三测）
- 透视投影：投影中心与投影平面的距离是有限的
- 一点透视
- 两点透视
- 三点透视

## 平行投影

平行投影是投影线相互平行的投影。若投影线垂直于投影面则称正投影，若投影面倾斜于投影面则称斜投影。

### 正交投影

正交投影是一系列用于显示三维物体的轮廓、细节或精确测量结果的变换方法。通常又称作截面图、鸟瞰图或立面图。

当视平面的法向（即摄像机的朝向）平行于笛卡尔坐标系三根坐标轴中的一根，数学变换定义如下：

若使用一个平行于y轴（侧视图）的正交投影将三维点$a_x$, $a_y$, $a_z$投影到二维平面上得到二维点$b_x$, $b_y$，可以使用如下公式

$$b_x = s_x a_x + c_x$$

$$b_y = s_z a_z + c_z$$

其中向量s是一个任意的缩放因子，而c是一个任意的偏移量。这些常量可自由选择，通常用于将视口调整到一个合适的位置。该投影变换同样可以使用矩阵表示（为清晰起见引入临时向量d）

$$<pre> \begin{bmatrix} {d_x } \\ {d_y } \\ \end{bmatrix} = \begin{bmatrix} 1 & 0 & 0 \\ 0 & 0 & 1 \\ </pre> \end{bmatrix}\begin{bmatrix} <pre> {a_x } \\ {a_y } \\ {a_z } \\ </pre> \end{bmatrix}$$

$$<pre> \begin{bmatrix} {b_x } \\ {b_y } \\ </pre> \end{bmatrix} = \begin{bmatrix} <pre> {s_x } & 0 \\ 0 & {s_z } \\ </pre> \end{bmatrix}\begin{bmatrix} <pre> {d_x } \\ {d_y } \\ </pre> \end{bmatrix} + \begin{bmatrix} <pre> {c_x } \\ {c_z } \\ </pre> \end{bmatrix}.$$

虽然正交投影产生的图像在一定程度上反映了物体的三维特性，但此类投影图像和实际观测到的并不相同。特别是对于相同长度的平行线段，无论离虚拟观察者（摄像机）远近与否，它们都会在正交投影中显示为相同长度。这会导致较近的线段看起来被缩短了。

### 斜投影

斜投影不像正交投影一样投影线垂直于投影面，而是投影线与投影面成非90度的斜角。

## 透视投影

透视投影的定义更为复杂。可以将其理解为透过摄像机取景器对于被投影物体进行观察。摄像机的位置、朝向和视野都将影响投影变换的结果。我们定义以下变量来对这一变换进行描述：

- $\mathbf{a}_{x,y,z}$：将被投影的三维空间中的点。
- $\mathbf{c}_{x,y,z}$：摄像机的位置。
- $\mathbf{\theta}_{x,y,z}$：摄像机的旋转角度。当 $\mathbf{c}_{x,y,z}$=且 $\mathbf{\theta}_{x,y,z}$=, 三维向量将被投影到二维向量。
- $\mathbf{e}_{x,y,z}$：观测者相对显示平面的位置。

最终结果为：

- $\mathbf{b}_{x,y}$：$\mathbf{a}$所产生的二维投影。

首先我们定义点$\mathbf{d}_{x,y,z}$作为点$\mathbf{a}$向摄像机坐标系所作的变换，其中摄像机坐标系由摄像机的位置$\mathbf{c}$和旋转$\mathbf{\theta}_{x,y,z}$所决定。该过程为：先用$\mathbf{a}$减去$\mathbf{c}$，然后使用由$-\mathbf{\theta}$产生的旋转矩阵乘上该结果。该变换通常称为摄像机变换(注意该计算过程假设使用左手法则)：

$\begin{bmatrix} <pre> \mathbf{d}_x \\ \mathbf{d}_y \\ \mathbf{d}_z \\ </pre> \end{bmatrix}=\begin{bmatrix} <pre> 1 & 0 & 0 \\ 0 & {\cos ( \mathbf{- \theta}_x ) } & { - \sin ( \mathbf{- \theta}_x ) } \\ 0 & { \sin ( \mathbf{- \theta}_x ) } & { \cos ( \mathbf{- \theta}_x ) } \\ </pre> \end{bmatrix}\begin{bmatrix} <pre> { \cos ( \mathbf{- \theta}_y ) } & 0 & { \sin ( \mathbf{- \theta}_y ) } \\ 0 & 1 & 0 \\ { - \sin ( \mathbf{- \theta}_y ) } & 0 & { \cos ( \mathbf{- \theta}_y ) } \\ </pre> \end{bmatrix}\begin{bmatrix} <pre> { \cos ( \mathbf{- \theta}_z ) } & { - \sin ( \mathbf{- \theta}_z ) } & 0 \\ { \sin ( \mathbf{- \theta}_z ) } & { \cos ( \mathbf{- \theta}_z ) } & 0 \\ 0 & 0 & 1 \\ </pre> \end{bmatrix}\left( {\begin{bmatrix} <pre> \mathbf{a}_x \\ \mathbf{a}_y \\ \mathbf{a}_z \\ </pre> \end{bmatrix} - \begin{bmatrix} <pre> \mathbf{c}_x \\ \mathbf{c}_y \\ \mathbf{c}_z \\ </pre> \end{bmatrix}} \right)$

或者使用以下这种非矩阵表示的形式，其中角度的正负号与矩阵表示形式不同：

$$\begin{array}{lcl} <pre> d_x &= &\cos \theta_y\cdot(\sin \theta_z\cdot(a_y-c_y)+\cos \theta_z\cdot(a_x-c_x))-\sin \theta_y\cdot(a_z-c_z) \\ d_y &= &\sin \theta_x\cdot(\cos \theta_y\cdot(a_z-c_z)+\sin \theta_y\cdot(\sin \theta_z\cdot(a_y-c_y)+\cos \theta_z\cdot(a_x-c_x)))+\cos \theta_x\cdot(\cos \theta_z\cdot(a_y-c_y)-\sin \theta_z\cdot(a_x-c_x)) \\ d_z &= &\cos \theta_x\cdot(\cos \theta_y\cdot(a_z-c_z)+\sin \theta_y\cdot(\sin \theta_z\cdot(a_y-c_y)+\cos \theta_z\cdot(a_x-c_x)))-\sin \theta_x\cdot(\cos \theta_z\cdot(a_y-c_y)-\sin \theta_z\cdot(a_x-c_x)) \\ </pre> \end{array}$$

然后将变换后的该点通过以下方程投影到二维平面（此处投影平面为x/y平面，有时也使用x/z）:

$$\begin{array}{lcl} <pre> \mathbf{b}_x &= &(\mathbf{d}_x - \mathbf{e}_x) (\mathbf{e}_z / \mathbf{d}_z) \\ \mathbf{b}_y &= &(\mathbf{d}_y - \mathbf{e}_y) (\mathbf{e}_z / \mathbf{d}_z) \\ </pre> \end{array}$$

或在齐次坐标系下可以表示为：

$$\begin{bmatrix} <pre> \mathbf{f}_x \\ \mathbf{f}_y \\ \mathbf{f}_z \\ \mathbf{f}_w \\ </pre> \end{bmatrix}=\begin{bmatrix} <pre> 1 & 0 & 0 & -\mathbf{e}_x \\ 0 & 1 & 0 & -\mathbf{e}_y \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 1/\mathbf{e}_z & 0 \\ </pre> \end{bmatrix}\begin{bmatrix} <pre> \mathbf{d}_x \\ \mathbf{d}_y \\ \mathbf{d}_z \\ 1 \\ </pre> \end{bmatrix}$$

和

$$\begin{array}{lcl} <pre> \mathbf{b}_x &= &\mathbf{f}_x / \mathbf{f}_w \\ \mathbf{b}_y &= &\mathbf{f}_y / \mathbf{f}_w \\ </pre> \end{array}$$

观测者到显示平面的距离，$\mathbf{e}_z$，直接关系到视野的大小。$\alpha=2 \cdot \tan^{-1}(1/\mathbf{e}_z)$为可视角度。（这里假设屏幕的两角为(-1,-1)和(1,1)）

如果要在一些特定的显示设备上显示该二维平面，之后还要进行一些必要的剪裁和缩放操作。

## 图示

<image>

计算三维空间中位于Ax，Az的点在屏幕坐标x轴的位置：

$$screen\ x\ coordinate\ (Bx)\ =\ model\ x\ coordinate\ (Ax) \times \frac{distance\ from\ eye\ to\ screen\ (Bz)}{distance\ from\ eye\ to\ point\ (Az)}$$

对于y轴同样有:

$$screen\ y\ coordinate\ (By)\ =\ model\ y\ coordinate\ (Ay) \times \frac{distance\ from\ eye\ to\ screen\ (Bz)}{distance\ from\ eye\ to\ point\ (Az)}$$

(其中Ax和Ay是透视转换前物体在空间中的坐标)