文章目录
平移、旋转、缩放平移旋转1. 沿x轴旋转2. 沿y轴或者z轴旋转
缩放
是时候整理一波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⎦⎥⎥⎤=⎣⎢⎢⎡100001000010abc1⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
旋转
对于旋转,任何一个旋转都可以认为是沿着x,y,z轴分别旋转
α
\alpha
α,
β
\beta
β,
γ
\gamma
γ 度数,所以选旋转就先讲沿着某个轴向的旋转。这里以逆着坐标轴正向方向看去的顺时针为旋转的正向,就是你的视线朝向和坐标轴正向是相反的,(⊙o⊙)…我还是画个图吧,下图就是沿着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′=xL⋅cos(θ+α)L⋅sin(θ+α)
y
=
L
⋅
c
o
s
α
z
=
L
⋅
s
i
n
α
\begin{aligned} y =& L·cos\alpha\\ z =& L·sin\alpha \end{aligned}
y=z=L⋅cosαL⋅sinα 根据三角函数公式可以得到
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′=L⋅cos(α−θ)=L⋅(cosαcosθ−sinαsinθ)=ycosθ−zsinθL⋅sin(α−θ)=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]
⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡10000cosθsinθ00−sinθcosθ00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
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]
⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosθ0−sinθ00100sinθ0cosθ00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
对于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]
⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤ 那一个物体沿着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]
⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡cosγsinγ00−sinγcosγ0000100001⎦⎥⎥⎤⎣⎢⎢⎡cosβ0−sinβ00100sinβ0cosβ00001⎦⎥⎥⎤⎣⎢⎢⎡10000cosαsinα00−sinαcosα00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
[
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]
⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡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β00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤
缩放
缩放感觉也没的说,直接上公示,下面公式表示沿着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]
⎣⎢⎢⎡x′y′z′1⎦⎥⎥⎤=⎣⎢⎢⎡a0000b0000c00001⎦⎥⎥⎤⎣⎢⎢⎡xyz1⎦⎥⎥⎤