计算机图形学-Transformation

120 阅读3分钟

计算机图形学-Transformation

线性变换

齐次坐标

理解:将一个n维的坐标或者向量,使用n+1维来表示。

  1. 2D-Point = (x,y,1)

  2. 2D-Vector = [xy0]\begin{bmatrix}x \\y \\0 \\ \end{bmatrix}

  3. 3D-Point = (x,y,z,1)

  4. 3D-Vector = [xyz0]\begin{bmatrix}x \\y \\z \\ 0 \\ \end{bmatrix}

2D视图变换

缩放变换(Scale)

image.png

如图所示:很容易看出,变换后的每个点坐标,都是原坐标的S倍。

x=Sxy=Sy\begin{aligned} x'=S x \\ y'=S y \end{aligned}

联想矩阵的乘法计算:

[xy]=[s00s][xy]=[sx+0y0x+sy] \begin{bmatrix} x'\\ y'\\ \end{bmatrix} = \begin{bmatrix} s&0\\ 0&s\\ \end{bmatrix} \cdot \begin{bmatrix} x\\ y\\ \end{bmatrix} = \begin{bmatrix} s*x+0*y\\ 0*x+s*y\\ \end{bmatrix}

因此定义缩放矩阵=S

S=[Sx00Sy] S = \begin{bmatrix} S_x&0\\ 0&S_y\\ \end{bmatrix}

注意SxS_xSyS_y可以不等,此时会导致变形。

镜像变换(Reflection)

x=xy=y\begin{aligned} x'&=-x \\ y'&= y \end{aligned}

因此定义缩放矩阵=S

S=[1001] S = \begin{bmatrix} -1&0\\ 0&1\\ \end{bmatrix}

裁剪变换(Shear)

image.png

此时:裁剪后的图形:y=1axy'= \frac{1}{a}x' (计算的是0到点(a,1)这条线。其他地方要加上原本x的坐标)。 y不变。因此 y=yy = y'

x=x+ay=x+ayy=y\begin{aligned} x' &= x+ a \\ y'&= x + ay \\ y'&= y \\ \end{aligned}
[xy]=[1a01][xy] \begin{bmatrix} x'\\ y'\\ \end{bmatrix} = \begin{bmatrix} 1&a\\ 0&1\\ \end{bmatrix} \cdot \begin{bmatrix} x\\ y\\ \end{bmatrix}

因此定义裁剪矩阵=S

S=[1a01] S = \begin{bmatrix} 1&a\\ 0&1\\ \end{bmatrix}

旋转变换(Rotate)

image.png

x=xcos θ+(y)sin θy=ysin θ+ycos θ \begin{align*} x' &= x*cos\ \theta + (-y)*sin\ \theta \\ y' &= y*sin\ \theta + y* cos\ \theta \end{align*}

因此定义旋转矩阵=R

R=[cos θsin θsin θcos θ] R = \begin{bmatrix} cos\ \theta&-sin\ \theta\\ sin\ \theta&cos\ \theta\\ \end{bmatrix}

推导过程:

先假设矩阵

R=[ABCD] R = \begin{bmatrix} A&B\\ C&D\\ \end{bmatrix}

点p(1,0)旋转后求得:p'=(cosθ,sinθcos \theta,sin\theta)。即:

[ABCD][10]=[cos θsin θ] \begin{bmatrix} A&B\\ C&D\\ \end{bmatrix} \cdot \begin{bmatrix} 1\\ 0\\ \end{bmatrix} = \begin{bmatrix} cos\ \theta\\ sin\ \theta\\ \end{bmatrix}

推出:A=cosθA=cos \thetaC=sinθC = sin\theta

同理可推导:

点p(0,1), 旋转后求得:p'=(sinθ,cosθ-sin \theta,cos\theta)。即:

[cosθBsinθD][01]=[sinθcosθ] \begin{bmatrix} cos \theta&B\\ sin\theta&D\\ \end{bmatrix}\cdot \begin{bmatrix} 0\\ 1\\ \end{bmatrix} = \begin{bmatrix} -sin \theta\\ cos\theta\\ \end{bmatrix}

推出:B=sinθB=-sin \theta, D=cosθD = cos\theta

即:

R=[cos θsin θsin θcos θ] R = \begin{bmatrix} cos\ \theta&-sin\ \theta\\ sin\ \theta&cos\ \theta\\ \end{bmatrix}

复合变换(Composite)

具有顺序性,先平移再旋转的结果不等于先旋转再平移。即:

R45T(1,0)T(1,0)R45R_{45} · T_{(1,0)} \neq T_{(1,0)} · R_{45}

复合变换矩阵计算:从右向左。

旋转矩阵、缩放矩阵、裁剪矩阵、镜像矩阵总结:

都是线性变换,都可以用矩阵来表示这几种变换。即:

[xy]=[abcd][xy]\begin{bmatrix} x'\\ y'\\ \end{bmatrix} = \begin{bmatrix} a&b\\ c&d\\ \end{bmatrix} \cdot \begin{bmatrix} x\\ y\\ \end{bmatrix}

即:

x=ax+byy=cx+dy\begin{aligned} x'=ax+by \\ y'= cx+ dy \end{aligned}

即:x=Mxx'=Mx

视图变换:以上结果均是基于坐标原点来平移缩放旋转等操作。

实际上:如果不是绕着原点做视图变换:

可以先将 视图变换的 "原点" 平移到坐标原点(0,0)。再做变换,再平移回去。

T(c)R(α)T(c) T_{(c)} · R_{(\alpha)} · T_{(-c)}

平移变换(Translation)

x=x+txy=y+ty\begin{aligned} x'=x+t_x \\ y'= y+ t_y \end{aligned}

得出:平移变换不是线性变换

[xy]=[abcd][xy]+[txty] \begin{bmatrix} x'\\ y'\\ \end{bmatrix} = \begin{bmatrix} a&b\\ c&d\\ \end{bmatrix}\cdot \begin{bmatrix} x\\ y\\ \end{bmatrix}+ \begin{bmatrix} t_x\\ t_y\\ \end{bmatrix}

但是我们不想让平移变换成为一种特殊的变换表示,所以我们引入了齐次坐标的概念来解决这个问题,也不是问题吧,就是解决这个特殊存在。

[xyw]=[10tx01ty001][xy1]=[x+txy+ty1] \begin{bmatrix} x'\\ y'\\ w' \end{bmatrix} = \begin{bmatrix} 1&0&t_x\\ 0&1&t_y\\ 0&0&1\\ \end{bmatrix}\cdot \begin{bmatrix} x\\ y\\ 1\\ \end{bmatrix} = \begin{bmatrix} x+t_x\\ y+t_y\\ 1\\ \end{bmatrix}

3D视图变换

平移变换(Translation)

x=x+txy=x+tyz=z+tz\begin{aligned} x' &=x + t_x \\ y'&= x + t_y \\ z'&= z + t_z \end{aligned}
[xyz1]=[abctxdeftyhijtz0001][xyz1] \begin{bmatrix} x'\\ y'\\ z'\\ 1 \end{bmatrix} = \begin{bmatrix} a&b&c&t_x\\ d&e&f&t_y\\ h&i&j&t_z\\ 0&0&0&1\\ \end{bmatrix} \cdot \begin{bmatrix} x\\ y\\ z\\ 1\\ \end{bmatrix}

类似2D模式下的平移变换因此可求出平移矩阵:

T(tx,ty,tz)=[100tx010ty001tz0001] T_{(t_x,t_y,t_z)} = \begin{bmatrix} 1&0&0&t_x\\ 0&1&0&t_y\\ 0&0&1&t_z\\ 0&0&0&1\\ \end{bmatrix}

缩放变换(Scale)

类似2D模式下的缩放变换因此可求出缩放矩阵:

S(sx,sy,sz)=[sx0000sy0000sz00001] S_{(s_x,s_y,s_z)} = \begin{bmatrix} s_x&0&0&0\\ 0&s_y&0&0\\ 0&0&s_z&0\\ 0&0&0&1\\ \end{bmatrix}

旋转变换(Rotates)

在三维坐标系下求解过程:

  1. 我们可以先考虑简单情况:假设只绕x轴渲染 α\alpha 度,其他轴不变。

image.png

此时:x保持不变。简化成了在z和y平面上的旋转:

很容易写出绕x轴的旋转矩阵:

Rx(α)=[10000cosαsinα00sinαcosα00001] R_{x(\alpha)} = \begin{bmatrix} 1&0&0&0\\ 0 & cos\alpha & -sin \alpha & 0\\ 0 & sin\alpha & cos\alpha & 0\\ 0&0&0&1\\ \end{bmatrix}
  1. 假设只绕z轴渲染 α\alpha 度,其他轴不变。

同理:z保持不变。简化成了在x和y平面上的旋转:

很容易写出旋转矩阵:

Rz(α)=[cosαsinα00sinαcosα0000100001] R_{z(\alpha)} = \begin{bmatrix} cos\alpha & -sin \alpha & 0 & 0 \\ sin\alpha & cos\alpha & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}
  1. 假设只绕y轴渲染 α\alpha 度,其他轴不变。

同理:y保持不变。简化成了在x和z平面上的旋转:

Ry(α)=[cosα0sinα00100sinα0cosα00001] R_{y(\alpha)} = \begin{bmatrix} cos\alpha & 0 & sin \alpha & 0 \\ 0 & 1 & 0 & 0 \\ -sin \alpha & 0 & cos\alpha & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}

解释:为什么sinαsin \alpha符号变了?

定义规则:我们默认定义

  • 逆时针方向为旋转方向。

  • 右手螺旋定则

根据右手定则可以判断:

  1. 绕x轴旋转,此时由 yzy \rightarrow z 旋转,大拇指方向指向x轴正方向。符号无异常。

  2. 绕z轴旋转,同理:即2d模式下的旋转由xyx \rightarrow y旋转,大拇指方向指向z轴正方向(屏幕外)。符号无异常。

  3. 绕y轴旋转:此时由zxz \rightarrow x,此时大拇指方向指向y轴正方向。符号无异常。此时需要反过来:即从xzx \rightarrow z旋转了α-\alpha角度。即:

sin(α)=sin(α)cos(α)=cos(α) \begin{align*} sin(-\alpha) &=-sin(\alpha) \\ cos(-\alpha) &= cos(\alpha) \end{align*}

因此:

Ry(α)=[cosα0sinα00100sinα0cosα00001] R_{y(\alpha)} = \begin{bmatrix} cos\alpha & 0 & sin \alpha & 0 \\ 0 & 1 & 0 & 0 \\ -sin \alpha & 0 & cos\alpha & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}

因此3维的旋转都可以分解成绕着不同轴的旋转的组合

Rxyz(α,β,γ)=Rx(α)Ry(β)Rz(γ) R_{xyz(\alpha,\beta,\gamma)} = R_{x(\alpha)} \cdot R_{y(\beta)} \cdot R_{z(\gamma)}

todo: 罗德里格旋转公式推导(Rodrigues' rotation formula)

投影变换

正交投影

透视投影

如图所示:

image.png

透视投影的推导:

问题简化:先挤压成正视投影,在利用正式投影进行投影。

定义规则

  • 近裁剪面保持不变

  • 远裁剪面向内挤压,Z保持不变。

  • ff为远裁剪面距离。

  • nn为近裁剪面距离。

  • 远裁剪面的中心点保持不变。(向内挤压,远裁剪面中心点坐标为 p(0,0,f,1)p(0,0,f,1) )。

我们假设沿着X轴负方向观察物体:

image.png

远裁剪面上一点:p(x,y,z,1)p(x,y,z,1)

经过透视投影M后变成了 p(x,y,z,1)p'(x',y',z',1)

Mpersportho[xyz1]=[xyz1] M_{persp\rightarrow ortho} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix} = \begin{bmatrix} x' \\ y' \\ z' \\ 1 \\ \end{bmatrix}

根据相似三角形:

y=nzy y'=\frac{n}{z} \cdot y
x=nzx x'=\frac{n}{z} \cdot x

代入上式得到:

M[xyz1]=[nzxnzyz1] M \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix} = \begin{bmatrix} \frac{n}{z} \cdot x \\ \frac{n}{z} \cdot y \\ z' \\ 1 \\ \end{bmatrix}

根据齐次坐标定义:

在三维中:空间中任意一个点(x,y,z,1)(x, y, z, 1), (kx,ky,kz,k!=0)(kx, ky, kz, k != 0), (xz,yz,z2,z!=0)(xz, yz, z2, z != 0) 都表示的是同一个点 (x, y, z)。

因此

Mpersportho[xyz1]=[nxnyzzz] M_{persp\rightarrow ortho} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \\ \end{bmatrix} = \begin{bmatrix} nx \\ ny \\ z'*z \\ z \\ \end{bmatrix}

此时很容易得到:

Mpersportho=[n0000n00????0010] M_{persp\rightarrow ortho} = \begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ ? & ? & ? & ? \\ 0 & 0 & 1 & 0 \\ \end{bmatrix}

根据规则定义:

  • 近裁剪面保持不变。所以近裁剪面的点经过$

M_{persp\rightarrow ortho}$ 后保持不变。

我们假设M的第三行为:

M(3j)persportho=[ABCD] M_{(3j) persp\rightarrow ortho} = \begin{bmatrix} A & B & C & D \\ \end{bmatrix}

近裁剪面有一点为 N(x,y,n,1) 投影后保持不变

根据齐次坐标

Mpersportho[xyn1]=[xyn1]==[nxnyn2n] M_{persp\rightarrow ortho} \cdot \begin{bmatrix} x \\ y \\ n \\ 1 \\ \end{bmatrix} = \begin{bmatrix} x \\ y \\ n \\ 1 \\ \end{bmatrix} == \begin{bmatrix} nx \\ ny \\ n^2 \\ n \\ \end{bmatrix}
[ABCD][xyn1]=n2 \begin{bmatrix} A & B & C & D \\ \end{bmatrix} \cdot \begin{bmatrix} x \\ y \\ n \\ 1 \\ \end{bmatrix} = n^2

因为n是近裁剪面的距离,n为常数。

因此 Ax+By+Cn+D=n2Ax+By+Cn +D = n^2

因此 必然:A=0,B=0。

根据规则定义:

  • 远裁剪面的中心点保持不变。(向内挤压,远裁剪面中心点坐标为 k(0,0,f,1)k(0,0,f,1)

我们取远裁剪面的中心点为 K(0,0,f,1)K(0,0,f,1)

中心点经过投影后也保持不变.K(0,0,f,1)K'(0,0,f,1)

根据齐次坐标

Mpersportho[00f1]=[00f1]==[00f2f] M_{persp\rightarrow ortho} \cdot \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \\ \end{bmatrix} = \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \\ \end{bmatrix} == \begin{bmatrix} 0 \\ 0 \\ f^2 \\ f \\ \end{bmatrix}
[00CD][00f1]=f2 \begin{bmatrix} 0 & 0 & C & D \\ \end{bmatrix} \cdot \begin{bmatrix} 0 \\ 0 \\ f \\ 1 \\ \end{bmatrix} = f^2

联合以上:

Cn+D=n2Cf+D=f2 Cn+D=n^2 \\ Cf+D=f^2

得出:

C=n+fD=nf \begin{align*} C &=n+f \\ D &=-nf \end{align*}

因此第三行:

M(3j)persportho=[00n+fnf] M_{(3j) persp\rightarrow ortho} = \begin{bmatrix} 0 & 0 & n+f & -nf \\ \end{bmatrix}

即:

Mpersportho=[n0000n0000n+fnf0010] M_{persp\rightarrow ortho} = \begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n+f & -nf \\ 0 & 0 & 1 & 0 \\ \end{bmatrix}

因此得出:

Mpersp=MorthoMpersportho M_{persp} = M_{ortho} \cdot M_{persp\rightarrow ortho}