数学


坐标转换

从基 B 的坐标转换到基 B′ 的坐标:

[v]B=(B)1B[v]B[v]_{B^′}​=(B^′)^{−1}B[v]_B​

变基矩阵

PBB=(B)1BP_{B→B^′}​=(B^′)^{−1}B​

旋转θ\theta矩阵

[cosθ,sinθ,0sinθ,cosθ,00,0,1]\begin{bmatrix} \cos\theta,&-\sin\theta,&0 \\ \sin\theta,&\cos\theta ,&0 \\ 0,&0,&1 \end{bmatrix}

Bresenham 直线算法

计算机图形学中经典的光栅化直线算法,核心思想是:利用整数增量计算,选择最接近理想直线的像素。对于0ΔyΔx0≤Δy≤Δx

p0=2ΔyΔxp_0​=2Δy−Δx

p<0⇒E​

p0NEp≥0⇒NE​

E:p←p+2Δy​ $$$$ NE:p←p+2Δy−2Δx​

### 透视投影矩阵 - 相机位于原点 - 相机看向 (-Z) - 近平面 (z=-n) - 远平面 (z=-f) - NDC 范围:$x,y,z\in[-1,1]$ 投影:设近平面距离为$n>0$,根据相似三角形

x’=-\frac{{nx}}{z}

相机空间向投影空间的变换矩阵$P$

P\begin{bmatrix} x \ y \ z \ 1 \end{bmatrix}= \begin{bmatrix} x_c \ y_c \ z_c \ w_c \end{bmatrix}

再行透视除法:再行透视除法:

x_{ndc}=\frac{x_c}{w_c}

令:令:

x_{c}=x,w_{c}=-\frac{z}{n}

实际工程中通常把n的比例吸收到矩阵中,因此可以简单理解为:实际工程中通常把n的比例吸收到矩阵中,因此可以简单理解为:

w_c=-z

这是透视投影矩阵最后一行出现(1)的根本原因。在近平面上进行线性映射:这是透视投影矩阵最后一行出现 (-1) 的根本原因。 在近平面上进行线性映射:

x_{ndc} \frac{-2nx/z-(r+l)}{r-l}

为了让它能够通过透视除法得到,由:为了让它能够通过透视除法得到,由:

w_c=-z$$ 可得:

xc=2nrlx+r+lrlzx_c= \frac{2n}{r-l}x + \frac{r+l}{r-l}z

同理

yc=2ntby+t+btbzy_c= \frac{2n}{t-b}y + \frac{t+b}{t-b}z

推导 (z) 方向,假设:

zc=Az+Bz_c=Az+B

那么:

zndc=Az+Bzz_{ndc}=\frac{Az+B}{-z}

根据nnff映射到[1,1][-1,1],所以:

{1=ABn1=A+Bf\left\{ \begin{aligned} -1 &= A-\frac{B}{n} \\ 1 &= A+\frac{B}{f} \end{aligned} \right.

解得:

{A=f+nfnB=2fnfn\left\{\begin{align}A & =-\frac{f+n}{f-n} \\ B & =-\frac{2fn}{f-n} \end{align}\right.

因此:

zc=f+nfnz2fnfnz_c= -\frac{f+n}{f-n}z -\frac{2fn}{f-n} [xcyczcwc]=[2nrl0r+lrl002ntbt+btb000f+nfn2fnfn0010][xyz1]\begin{bmatrix} x_c \\ y_c\\ z_c\\ w_c \end{bmatrix} = \begin{bmatrix} \frac{2n}{r-l}&0&\frac{r+l}{r-l}&0\\ 0&\frac{2n}{t-b}&\frac{t+b}{t-b}&0\\ 0&0&-\frac{f+n}{f-n}&-\frac{2fn}{f-n}\\ 0&0&-1&0 \end{bmatrix} \begin{bmatrix} x\\y\\z\\1 \end{bmatrix}

所以非对称视锥体(off-axis frustum)的透视投影矩阵:

P=[2nrl0r+lrl002ntbt+btb000f+nfn2fnfn0010]P= \begin{bmatrix} \frac{2n}{r-l}&0&\frac{r+l}{r-l}&0\\ 0&\frac{2n}{t-b}&\frac{t+b}{t-b}&0\\ 0&0&-\frac{f+n}{f-n}&-\frac{2fn}{f-n}\\ 0&0&-1&0 \end{bmatrix}

实际经常使用左右、上下对称的视锥体.如果使用垂直视场角 (θ\theta) 和宽高比 (aa),最终:

P=[1atan(θ/2)00001tan(θ/2)0000f+nfn2fnfn0010]P= \begin{bmatrix} \frac1{a\tan(\theta/2)}&0&0&0\\ 0&\frac1{\tan(\theta/2)}&0&0\\ 0&0&-\frac{f+n}{f-n}&-\frac{2fn}{f-n}\\ 0&0&-1&0 \end{bmatrix}

正交投影矩阵

不需要利用 (w) 实现透视缩放。

xndc=2rlxr+lrlx_{ndc}=\frac2{r-l}x-\frac{r+l}{r-l} yndc=2tbyt+btby_{ndc}=\frac2{t-b}y-\frac{t+b}{t-b}

OpenGL 中zz[n,f][-n,-f]映射到[1,1][-1,1],最终:

Portho=[2rl00r+lrl02tb0t+btb002fnf+nfn0001]P_{ortho}= \begin{bmatrix} \frac2{r-l}&0&0&-\frac{r+l}{r-l}\\ 0&\frac2{t-b}&0&-\frac{t+b}{t-b}\\ 0&0&-\frac2{f-n}&-\frac{f+n}{f-n}\\ 0&0&0&1 \end{bmatrix}

重心坐标:

P=αA+βB+γC1=α+β+γ\begin{align} P&=αA+βB+γC​ \\ 1&=α+β+γ \end{align}​

普通线性插值:

C=αCA+βCB+γCCC=αC_{A}​+βC_{B}​+γC_{C}​

透视校正插值:

C=α/wA​+β/wB​+γ/wC​αCA​/wA​+βCB​/wB​+γCC​/wC​ $$​​