Tag DirectX下的博客主要用于记录DirectX的学习过程,主要参考《DirectX 12 3D 游戏实战开发》。本篇主要是顺着DX12龙书的节奏温习线性代数中的线性变换。
线性变换
定义
关于线性变换的定义有很多种,这里参考龙书,给出3D图形学的线性变换定义。 数学函数τ是线性变换当且仅当:τ(→u+→v)=τ(→u)+τ(→v)τ(k→u)=kτ(→u)
矩阵表示法
线性变换是可以用矩阵表示的。 设→u=(x,y,z),→u也可以写作→u=x→i+y→j+z→k→i,→j,→k为→u所在坐标系的单位正交基那么关于→u的线性变换τ也可以写作τ(→u)=xτ(→i)+yτ(→j)+zτ(→k)可以看出这是一种线性组合,可以用矩阵表示为:τ(→u)=xτ(→i)+yτ(→j)+zτ(→k)=[x,y,z][τ(→i)τ(→j)τ(→k)]
缩放
缩放也是一种线性变换。把物体关于x、y、z轴的缩放系数分别记为Sx、Sy、Sz,并记缩放变换为S显然,S(→i)=(Sx,0,0),S(→j)=(0,Sy,0),S(→k)=(0,0,Sz)那么缩放矩阵即[Sx000Sy000Sz]根据缩放变换的性质我们也很容易得到其逆变换对应的矩阵(即缩放矩阵的逆矩阵)为[1/Sx0001/Sy0001/Sz]旋转
旋转也是一种线性变换。 对于→v绕轴→n顺时针旋转θ,为了方便分析,把→v正交分解为正交于→n的部分→v⊥和平行于→n的部分proj→n(→v)假设→n是单位向量,那么proj→n(→v)=(→n˙→v)→n,→v⊥=→v−proj→n(→v)记旋转变换为R,显然旋转操作并不会改变proj→n(→v),故R→n(→v)=proj→n(→v)+R→n(→v⊥)记→v和→n的夹角为α,那么|→n×→v|=|→n||→v|sinα=|→v|sinα=|→v⊥|那么R→n(→v⊥)=→v⊥cosθ+(→n×→v)sinθ综上,R→n(→v)=proj→n(→v)+R→n(→v⊥)=cosθ→v+(1−cosθ)(→n˙→v)→n+sinθ(→n×→v)把→i带入R即可得到R→n(→i)=(c+(1−c)x2,(1−c)xy+sz,(1−c)xz−sy)同理可得R→n(→j)和R→n(→k)那么旋转矩阵为[c+(1−c)x2(1−c)xy+sz(1−c)xz−sy(1−c)xy−szc+(1−c)y2(1−c)yz+sx(1−c)xz+sy(1−c)yz−sxc+(1−c)z2]其中,c=cosθ,s=sinθ,x=→nx,y=→ny,z=→nz 旋转矩阵都是正交矩阵,即矩阵中的任两个行向量都互相正交,正交矩阵的转置即逆矩阵。由此我们可以高效得出旋转变换的逆变换对应的矩阵。
特别地,如果选择绕坐标轴旋转,代入标准正交基即可得到绕x、y、z轴旋转对应的矩阵: Rx=[10000cosθsinθ00−sinθcosθ00001],Ry=[cosθ0−sinθ00100sinθ0cosθ00001],Rz=[cosθsinθ00−sinθcosθ0000100001] 这里延伸多一维是为了与仿射变换的矩阵表示统一。