3d变换基础:平移、旋转、缩放(仿射变换)详解——公式推导


是时候整理一波3d变换相关的知识了。模型的变换可以认为是空间中一堆点的变换,三维空间中,(x,y,z)可以认为是点,也可以认为是一个向量,因此,人们引入的第4个维度来标识是点还是向量,这个4维空间就叫 仿射空间,具体可以参考 CV及CG数学基础:空间,在仿射空间中,(x,y,z,0)标识向量,而(x,y,z,1)表示点。

平移、旋转、缩放

平移

平移没什么好说的,(x,y,z,1)向x,y,z轴分别移动a,b,c单位长度后变成(x+a, y+b, z+c, 1)。写成矩阵相乘的方式即为:

[ x + a y + b z + c 1 ] = [ 1 0 0 a 0 1 0 b 0 0 1 c 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x+a \\ y+b \\ z+c \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} 1 & 0 & 0 & a\\ 0 & 1 & 0 & b \\ 0 & 0 & 1 & c \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] x+ay+bz+c1=100001000010abc1xyz1

旋转

对于旋转,任何一个旋转都可以认为是沿着x,y,z轴分别旋转 α \alpha α, β \beta β, γ \gamma γ 度数,所以选旋转就先讲沿着某个轴向的旋转。这里以逆着坐标轴正向方向看去的顺时针为旋转的正向,就是你的视线朝向和坐标轴正向是相反的,(⊙o⊙)…我还是画个图吧,下图就是沿着z轴旋转的正向了哈~

延z轴旋转的正向

1. 沿x轴旋转

我画的!好看吗?
嗯!这里推一波公式,其实很简单,就是三角函数。
如上图左边,A点沿着x轴旋转一定角度变成A’,为了更容易看,右图是左图的左视图,记旋转的角度为 θ \theta θ, 旋转后得到的A’与旋转中心连线与y轴正方向的夹角为 α \alpha α(图中的 α \alpha α是个负值),记A’与旋转中心连线的长度为L(A与旋转中心连线的长度也是L),那么,显而易见,有:

x ′ = x y ′ = L ⋅ c o s ( θ + α ) z ′ = L ⋅ s i n ( θ + α ) \begin{aligned} x' =& x\\ y' =& L·cos(\theta + \alpha)\\ z' =& L·sin(\theta + \alpha) \end{aligned} x=y=z=xLcos(θ+α)Lsin(θ+α)

y = L ⋅ c o s α z = L ⋅ s i n α \begin{aligned} y =& L·cos\alpha\\ z =& L·sin\alpha \end{aligned} y=z=LcosαLsinα
根据三角函数公式可以得到
y ′ = L ⋅ c o s ( α − θ ) = L ⋅ ( c o s α c o s θ − s i n α s i n θ ) = y c o s θ − z s i n θ z ′ = L ⋅ s i n ( α − θ ) = L ⋅ ( s i n θ c o s α + c o s θ s i n α ) = y s i n θ + z c o s θ \begin{aligned} y' =& L·cos(\alpha - \theta) = L·(cos\alpha cos\theta - sin\alpha sin\theta) = ycos\theta -zsin\theta\\ z' =& L·sin(\alpha - \theta) = L·(sin\theta cos\alpha + cos\theta sin\alpha ) = ysin\theta + zcos\theta \end{aligned} y=z=Lcos(αθ)=L(cosαcosθsinαsinθ)=ycosθzsinθLsin(αθ)=L(sinθcosα+cosθsinα)=ysinθ+zcosθ
综上,有:
x ′ = x y ′ = y c o s θ − z s i n θ z ′ = y s i n θ + z c o s θ \begin{aligned} x' =& x\\ y' =& ycos\theta -zsin\theta\\ z' =&ysin\theta + zcos\theta \end{aligned} x=y=z=xycosθzsinθysinθ+zcosθ
现在就可以写成漂亮的矩阵形式了:
[ x ′ y ′ z ′ 1 ] = [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & cos\theta & -sin\theta & 0 \\ 0 & sin\theta & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] xyz1=10000cosθsinθ00sinθcosθ00001xyz1

2. 沿y轴或者z轴旋转

推了x轴的,其他两个轴向其实原理都是一样的。
对于y轴,可以简单把y轴和x轴对调,也就是公式里的x,y对调,不过这样子的话,z轴的方向会反过来,所以再把z相关的加个符号就好了。
公式如下:
y ′ = y x ′ = x c o s θ + z s i n θ z ′ = − x s i n θ + z c o s θ \begin{aligned} y' =& y\\ x' =& xcos\theta +zsin\theta\\ z' =&-xsin\theta +zcos\theta \end{aligned} y=x=z=yxcosθ+zsinθxsinθ+zcosθ
写成漂亮的矩阵形式就是:
[ x ′ y ′ z ′ 1 ] = [ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\theta &0 & sin\theta & 0 \\ 0 & 1 & 0 & 0\\ -sin\theta & 0 & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] xyz1=cosθ0sinθ00100sinθ0cosθ00001xyz1

对于z轴,x,z互换,y置反,直接上公式:
z ′ = z y ′ = y c o s θ + x s i n θ x ′ = − y s i n θ + x c o s θ \begin{aligned} z' =& z\\ y' =& ycos\theta +xsin\theta\\ x' =&-ysin\theta + xcos\theta \end{aligned} z=y=x=zycosθ+xsinθysinθ+xcosθ
矩阵形式:
[ x ′ y ′ z ′ 1 ] = [ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\theta & -sin\theta&0 & 0 \\ sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] xyz1=cosθsinθ00sinθcosθ0000100001xyz1
那一个物体沿着x,y,z 轴分别旋转 α \alpha α, β \beta β, γ \gamma γ 度数就把3个矩阵相乘就好了。

[ x ′ y ′ z ′ 1 ] = [ c o s γ − s i n γ 0 0 s i n γ c o s γ 0 0 0 0 1 0 0 0 0 1 ] [ c o s β 0 s i n β 0 0 1 0 0 − s i n β 0 c o s β 0 0 0 0 1 ] [ 1 0 0 0 0 c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\gamma& -sin\gamma&0 & 0 \\ sin\gamma& cos\gamma& 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} cos\beta&0 & sin\beta& 0 \\ 0 & 1 & 0 & 0\\ -sin\beta& 0 & cos\beta& 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 & 0\\ 0 & cos\alpha & -sin\alpha & 0 \\ 0 & sin\alpha & cos\alpha & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] xyz1=cosγsinγ00sinγcosγ0000100001cosβ0sinβ00100sinβ0cosβ0000110000cosαsinα00sinαcosα00001xyz1
[ x ′ y ′ z ′ 1 ] = [ c o s β c o s γ s i n α s i n β c o s γ − s i n γ c o s α s i n β c o s α c o s γ + s i n α s i n γ 0 c o s β s i n γ c o s α c o s γ + s i n α s i n β s i n γ − s i n α c o s γ + s i n γ s i n β c o s α 0 − s i n β s i n α c o s β c o s α c o s β 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} cos\beta cos\gamma & sin\alpha sin\beta cos\gamma - sin\gamma cos\alpha & sin\beta cos\alpha cos\gamma +sin\alpha sin\gamma & 0\\ cos\beta sin\gamma & cos\alpha cos\gamma + sin\alpha sin\beta sin\gamma & -sin\alpha cos\gamma + sin\gamma sin\beta cos\alpha & 0 \\ -sin\beta & sin\alpha cos\beta& cos\alpha cos\beta& 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] xyz1=cosβcosγcosβsinγsinβ0sinαsinβcosγsinγcosαcosαcosγ+sinαsinβsinγsinαcosβ0sinβcosαcosγ+sinαsinγsinαcosγ+sinγsinβcosαcosαcosβ00001xyz1

缩放

缩放感觉也没的说,直接上公示,下面公式表示沿着x,y,z轴分别缩放a,b,c倍:
[ x ′ y ′ z ′ 1 ] = [ a 0 0 0 0 b 0 0 0 0 c 0 0 0 0 1 ] [ x y z 1 ] \left[ \begin{matrix} x' \\ y' \\ z' \\ 1\\ \end{matrix} \right] = \left[ \begin{matrix} a & 0 & 0 & 0\\ 0 & b & 0 & 0 \\ 0 & 0 & c & 0 \\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} x \\ y \\ z \\ 1\\ \end{matrix} \right] xyz1=a0000b0000c00001xyz1

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值