数学基础
默认为列向量,各种API都是默认列向量
点积(数量积、标量积、内积)
两个向量长度和他们夹角的积。
$\vec{a} \cdot \vec{b} = ||a|| ||b|| cos \theta$
$\vec{a} \cdot \vec{b} = \left( \begin{matrix}
x_1\y_1\z_1
\end{matrix}\right)\cdot\left( \begin{matrix}
x_2\y_2\z_2
\end{matrix}\right) = x_1x_2+y_1y_2+z_1z_2$
- 结果是个数,与夹角余弦值成正比。
- 作用
- 求两向量夹角$\theta$、余弦值
- 求投影
- 求余弦相似度,看两个向量有多接近
- 求向量方向,点乘大于零为同向,小于零反向,等于零垂直,等于1重合,等于-1完全反向。
叉积
$\vec{z}=\vec{x} \times \vec{y} = - \vec{y} \times \vec{x}$ ,c的方向通过右手定则确定,右手四指顺着由a出发指向b,拇指方向即为c方向。
$||\vec{x} \times \vec{y}|| = ||x| |||y|| sin \theta$
$\vec{a} \times \vec{b} = \left( \begin{matrix}
x_1\y_1\z_1
\end{matrix}\right)\times\left( \begin{matrix}
x_2\y_2\z_2
\end{matrix}\right) = \left( \begin{matrix}
y_1z_2-y_2z_1\z_1y_2-x_1z_2\x_1y_2-y_1x_2
\end{matrix}\right)$
$\vec{a} \times \vec{b} = A^* \left( \begin{matrix}
x_2\y_2\z_2
\end{matrix}\right) = \left(\begin{matrix}0&-z_1&y_1\z_1&0&-x_1\-y_1&x_1&0
\end{matrix}\right) \left( \begin{matrix}
x_2\y_2\z_2
\end{matrix}\right)$
- 结果为另一个向量,且一定与ab垂直。
- 如果 $\vec{x} \times \vec{y} = - \vec{z} $,为左手坐标系,OpenGL、unity都是左手坐标系。
- 叉乘没有交换律,但有分配律,可以数乘
- $\vec{x} \times \vec{x} = 0 $
- 作用
- 判定左右
- 如图,如何判断a和b的左右关系,右手定则,a x b = c,c为正,b在a左侧,b x a = -c,a在b右边
- 判定内外
如图,判断点P是否在abc內部?
利用右手定则,AB x AP与BC x BP与CA x CP方向一致,所以点P在ABC内部。
矩阵
- 没有交换律,有分配律和结合律
- $(AB)T=BTA^T$
- $A A^{-1} =A^{-1}A=I$
- $(AB)^{-1} =B{-1}A$
MVP变换
- MVP变换:模型(model transformation)视图(view transformation)投影(projection transformation)变换
- 就像拍照一样,先人站好(模型变换),再调整好相机,并确定往哪拍(视图变换),然后拍照(投影变换)。我们看到的都是三维世界的二维投影。
- 模型变换
- 仿射变换=线性变换+平移
- 视图变换
模型变换(Model transformation)
二维变换
线性变换
$x^{'}=Mx$
不能表示平移
- 缩放变换
- 反射变换
- 切变
- 旋转
Scale缩放变换
- 均匀缩放
$x^{'}=sx$
$y^{'}=sy$
或
$\left( \begin{matrix}
x^{'} \ y^{'}
\end{matrix}\right) = \left(\begin{matrix}s&0\0&s
\end{matrix}\right) \left( \begin{matrix}
x\y
\end{matrix}\right)$ - 非均匀缩放
$\left( \begin{matrix}
x^{'} \ y^{'}
\end{matrix}\right) = \left(\begin{matrix}s_x&0\0&s_y
\end{matrix}\right) \left( \begin{matrix}
x\y
\end{matrix}\right)$
反射变换(对称)
- 以y轴对称
$\left( \begin{matrix}
x^{'} \ y^{'}
\end{matrix}\right) = \left(\begin{matrix}-1&0\0&1
\end{matrix}\right) \left( \begin{matrix}
x\y
\end{matrix}\right)$
切变 Shear Matrix
图中,所有的$y$坐标都没有变化,所有的$x$坐标都变成$x+ay$
$\left( \begin{matrix}
x^{'} \ y^{'}
\end{matrix}\right) = \left(\begin{matrix}1&a\0&1
\end{matrix}\right) \left( \begin{matrix}
x\y
\end{matrix}\right)$
旋转Rotate
- 默认以(0,0)为原点,逆时针方向旋转
$\left( \begin{matrix}
x^{'} \ y^{'}
\end{matrix}\right) = \left(\begin{matrix}cos \theta&-sin\theta\sin\theta&cos\theta
\end{matrix}\right) \left( \begin{matrix}
x\y
\end{matrix}\right)$ - 如果旋转$-\theta $角度:
$R_{-\theta}=\left(\begin{matrix}cos \theta&sin\theta\-sin\theta&cos\theta
\end{matrix}\right)=R^{-1}=R_\theta ^T$
如果一个矩阵的逆等于它的转置,那我们称这个矩阵为正交矩阵。
很重要:旋转矩阵$R_\theta$是正交矩阵
重要概念:齐次坐标
- 作用
- 实现一个统一模型
平移Translation
$x^{'}=x+t_x$
$y^{'}=y+t_y$
或
$\left( \begin{matrix}
x^{'} \ y^{'}
\end{matrix}\right) = \left(\begin{matrix}a&b\c&d
\end{matrix}\right) \left( \begin{matrix}
x\y
\end{matrix}\right)+\left( \begin{matrix}
t_x\t_y
\end{matrix}\right)$
- 平移不能表示成$x^{'}=Mx$,所以平移不是线性变换。
- 所以寻找一种统一的方法描述各种变换——引入齐次坐标。
- 首先将二维平面的点和向量升维
- 二维平面的点$=(x,y,1)^T$
- 二维平面向量$=(x,y,0)^T$
- 此时平移:
$\left( \begin{matrix}
x^{'} \ y{'}\z
\end{matrix}\right) = \left(\begin{matrix}1&0&t_x\0&1&t_y\0 &0& 1
\end{matrix}\right) \left( \begin{matrix}
x\y\1
\end{matrix}\right)=\left( \begin{matrix}
x+t_x\y+t_y\1
\end{matrix}\right)$ - 由于向量具有平移不变性,无论如何平移方向都不改变,所以向量不需要这个1。
- 事实上,2D点表示为$\left( \begin{matrix}
x\y\w
\end{matrix} \right)$,当$w\neq0$时,有$\left( \begin{matrix}
x/w\y/w\1
\end{matrix} \right)$,所以1是这么来的,所以易推当两个点相减时,表示为两点的中点。
注意
- 先执行线性变换,再平移,从未引入齐次坐标的平移公式能看出来
- 顺序不同,结果不同,因为矩阵乘法没有交换律,即:
$R_{45} \cdot T_{(1,0)} \neq T_{(1,0)} \cdot R_{45}$ - 矩阵执行,从右向左,如:先旋转45°,再向右平移一个单位:
$T_{1,0} \cdot R_{45} \left( \begin{matrix} x\y\z\end{matrix} \right)=\left(\begin{matrix}
1&1&0\
0&1&0\0&0&1
\end{matrix}\right)\left(\begin{matrix}
cos45&-sin45&0\
sin45&cos45&0\0&0&1
\end{matrix}\right)\left(\begin{matrix}
x\y\1
\end{matrix}\right)$
三维变换
线性变换
- 仍然引入齐次坐标:
三维平面上的点$=\left( \begin{matrix}
x,y,z,1
\end{matrix} \right)^T$
三维平面上的向量$=\left( \begin{matrix}
x,y,z,0
\end{matrix} \right)^T$
同样有:
$\left( \begin{matrix} x{'}\y\z^{'}\end{matrix} \right)=\left(\begin{matrix}
a&b&c&t_x\
d&e&f&t_y\g&h&i&t_z\0&0&0&1
\end{matrix}\right) \cdot \left(\begin{matrix}
x\y\z\1
\end{matrix}\right)$
旋转
$R_{xyz}(\alpha,\beta,\gamma)=R_x(\alpha)R_y(\beta)R_z(\gamma)$
罗德里格斯公式Rodrigues:
旋转轴n,旋转角度α,默认轴从原点开始,方向为最标轴方向
视图变换(View / Camera transformation)
-
定义相机:
- 位置:$\vec{e}$
- 朝向/方向:$\hat{g}$
- 上下方向:$\hat{t}$
-
约定俗成:标准位置:永远固定相机在原点,并往$-Z$方向看,以$+Y$为向上方向。这样方便
-
将任意位置相机挪到标准位置,如图所示:
$M_{view}=R_{view}T_{view}$
- 先进行平移,把 $\vec{e}$ 平移到原点
$T_{view}=\left( \begin{matrix}
1&0&0&-x_e \
0&1&0&-y_e \
0&0&1&1
\end{matrix} \right)$ - $\hat{g}$旋转至$-z$,$\hat{t}$旋转至$y$,但是不好转,所以可以考虑$y$旋转至$\hat{t}$,$-z$旋转至$\hat{g}$,有:
$R^{-1}{view}= \left( \begin{matrix}
x{\hat{g}}\times\hat{t} & x_t & x_{-g} & 0 \
y_{\hat{g}}\times\hat{t} & y_t & y_{-g} & 0 \
z_{\hat{g}}\times\hat{t} & z_t & z_{-g} & 0 \
0 & 0 & 0 & 1
\end{matrix} \right)$ - 由于旋转矩阵为正交矩阵,所以有:
$R_{view}=(R{-1}_{view})T=\left( \begin{matrix}
x_{\hat{g}}\times\hat{t} & y_{\hat{g}}\times\hat{t} & z_{\hat{g}}\times\hat{t} &0 \
x_t & y_t & z_t & 0 \
x_{-g} & y_{-g} & z_{-g} & 0 \
0 & 0 & 0 & 1 \
\end{matrix} \right)$
- 先进行平移,把 $\vec{e}$ 平移到原点
Projection (投影) transformation
两种投影方式:正交、透视
- 左图正交投影:原模型中平行的线依然平行,不会出现近大远小,多用于工程制图
- 右图为透视投影,模型中平行的线现在不再平行,近大远小,更接近现实世界。
Orthographic (正交) projection
- 平移至原点
- 缩放到$[-1,1]^2$范围内
如将一个任意位置的立方体$[l,r] \times [b,t] \times [f,n]$($[左,右] \times [下,上] \times [近,远]$)透视为一个正则(规范、标准)立方体(canonical cube)$[-1,1]^3$,
$M_{ortho}=\left( \begin{matrix}
\frac{2}{r-l} & 0 & 0 &0 \
0 & \frac{2}{t-b} & 0 & 0 \
0 & 0 & \frac{2}{n-f} & 0 \
0 & 0 & 0 & 1 \
\end{matrix} \right)\left( \begin{matrix}
1 & 0 & 0 & -\frac{r+l}{2} \
0 & 1 & 0 & -\frac{t+b}{2} \
0 & 0 & 1 & -\frac{n+f}{2} \
0 & 0 & 0 &1 \
\end{matrix} \right)$
此时尚未考虑旋转,且模型会被拉伸,暂时按下不表。
Perspective (透视) projection
- 铺垫:齐次坐标中某个点$(x,y,z,1)T$可以乘任意一个数还表示它本身,所以可以乘$z$,有$(xz,yz,z2,z)T$,都表示点$(x,y,z)T$。
- 原理:从相机这个点延伸出一个四棱锥,并规定近远。先挤压 再正交
侧面来看:
挤压后有:
$\left(\begin{matrix}
x\y\z\1
\end{matrix}\right)=\left(\begin{matrix}
nx/z\ny/z\unknow\1
\end{matrix}\right)==\left(\begin{matrix}
nx\ny\unknow\z
\end{matrix}\right)$
再往后完全没看懂,有空再说。