3D 变换(3D Transformation)
符号
本 note 里使用的是狄拉克符号:|r\rangle 表示列向量(等同于记号 \vec{r} 或者 \bm{r} 或点的三维坐标),\langle r| 表示行向量,\langle r|s\rangle 表示 |r\rangle 和 |s\rangle 的内积,不难看出,这也是 \langle r| 和 |s\rangle 的矩阵乘法。默认 3D 坐标的正交基为 |x\rangle,|y\rangle,|z\rangle。
平移、放缩和旋转
平移变换(translation):
- 点坐标 (x,y,z)\rightarrow (x+t_1,y+t_2,z+t_3)
- 不改变向量
放缩变换(scaling):
- 点坐标 (x,y,z)\rightarrow (s_1*x,s_2*y,s_3*z)
- 向量 (x,y,z)^T\rightarrow (s_1*x,s_2*y,s_3*z)^T
旋转变换(rotation):
绕任意轴旋转的公式推导如下:
- 求解向量 |r\rangle 绕单位向量 |n\rangle 旋转角度 \alpha 的变换矩阵:
- 首先把向量 |r\rangle 分解为沿着 |n\rangle 方向的分量 |r_{n}\rangle 和垂直于 |n\rangle 方向的分量 |r_{\bot}\rangle。运算过程如下:
- |r_n\rangle =\langle n|r\rangle|n\rangle=|n\rangle \langle n|r\rangle
- |r_{\bot}\rangle=|r\rangle-|r_n\rangle=(I-|n\rangle\langle n|)|r\rangle
- 显然只有垂直于 |n\rangle 的分量会被旋转改变。现在考虑 |n\rangle,\frac{|r_{\bot}\rangle}{|||r_{\bot}\rangle||} 和 \frac{1}{|||r_{\bot}\rangle||}|n\rangle\times |r_{\bot}\rangle=\frac{1}{|||r_{\bot}\rangle||}|n\rangle\times |r\rangle 构成的右手坐标系 C'。在坐标系 C' 下,|r_{\bot}\rangle 的坐标为 \left (0,|||r_{\bot}\rangle||, 0\right )^T,其绕 |n\rangle 的旋转 \alpha 后(旋转矩阵即为绕 x 轴的旋转矩阵)的坐标即为 \left (0,\cos(\alpha)|||r_{\bot}\rangle||, sin(\alpha)|||r_{\bot}\rangle||\right )^T,转换为原坐标系后向量为:\cos(\alpha) |r_{\bot}\rangle+\sin(\alpha) |n\rangle\times |r\rangle
- 至此已经得到 |r\rangle 旋转后的向量为:
- |r_n\rangle+\cos(\alpha)|r_{\bot}\rangle+\sin(\alpha)|n\rangle\times|r\rangle=
- [\cos(\alpha)I+(1-\cos(\alpha))|n\rangle\langle n|]|r\rangle+\sin(\alpha)|n\rangle\times |r\rangle
- 其中 |n\rangle\times |r\rangle=\begin{pmatrix}0&-n_z&n_y\\n_z&0&-n_x\\-n_y&n_x&0\\\end{pmatrix}|r\rangle。则得到旋转矩阵:
-
R(|n\rangle,\alpha)=\cos(\alpha)I+(1-\cos(\alpha))|n\rangle\langle n|+\sin(\alpha)\begin{pmatrix}0&-n_z&n_y\\n_z&0&-n_x\\-n_y&n_x&0\\\end{pmatrix}
- 首先把向量 |r\rangle 分解为沿着 |n\rangle 方向的分量 |r_{n}\rangle 和垂直于 |n\rangle 方向的分量 |r_{\bot}\rangle。运算过程如下:
绕 x,y,z 轴的旋转矩阵很容易得到,这里就不证了。
仿射变换(Affine Transformation)
首先,不难看出旋转和放缩都是线性的操作,故均可以表示为矩阵,而平移是非线性的(对于 position 点)。因此这三种操作的组合,即仿射变换需要写成 线性变换 + 平移项 的格式:
齐次坐标(Homogenous Coordinates)
为了去掉仿射变换中的平移项,将这三种变换统一表示为矩阵形式,引入齐次坐标可以去除该平移项。将原本的坐标 (x,y,z)^T 扩展为 (x,y,z,w)^T 四维。w=0 时表示 3D 向量坐标 (x,y,z)^T,w\neq 0 时表示位置坐标 (x/w,y/w,z/w)^T。则仿射变换可以写成 4×4 的线性变换矩阵:
此处 T_{linear} 是 3×3 的矩阵。0 表示子矩阵元素全为 0。
观测变换(Viewing Transformation)
视图变换(View Transformation)
又可以叫相机变换(Camera Transformation),即把相机从当前位置 |e\rangle 移动到原点并调整方向,使得镜头朝向 |g\rangle(look-at direction)变得与 Z 轴负方向一致,且镜头向上方向 |t\rangle(up direction)与 Y 轴一致。
[图片]
不难看出,相机变换的矩阵为一个平移与旋转的组合:
投影变换(Projection Transformation)
将物体从 3D 空间投影到 2D 画面,有正交投影(orthographic projection)和透视投影(perspective projection)两种。
[图片]
正交投影(Orthographic Projection)
- 相机在原点,向-Z 轴看,up direction 为 Y
- 物体 Z 轴被去掉
- 平移缩放物体到范围(即 x 和 y 轴范围在-1 和 1 之间)
通常做法:将 [l,r]\times [b,t]\times [f,n] 范围的立方体,平移缩放到 [-1,1]^3 的标准立方体上。
透视投影(Perspective Projection)
[图片]
相比正交投影,先多一步变换 M_{persp\rightarrow ortho}:把视锥体(frustum)"挤压"成立方体,并保证近平面上任意一点不变,远平面上 z 坐标不变(但是之间的平面 z 坐标会改变),不难看出该变换的作用是 (x,y,z)^T\rightarrow (nx/z,ny/z,z)^T,这种变换在 3D 坐标下不是线性的,无法写成矩阵。但引入齐次坐标后,(nx/z,ny/z,z,1)^T\Leftrightarrow (nx,ny,z^2,z)^T ,可以计算 M_{persp\rightarrow ortho}(x,y,z,1)^T=(nx,ny,z^2,z)^T 得到 M_{persp\rightarrow ortho} 的矩阵形式:
通过 fovY 和 aspect\_ratio 得到 l,r,b,t
之前使用 l(左边沿的 x 坐标),r(右边沿的 x 坐标),b(下边沿的 y 坐标),t(上边沿的 y 坐标)来表示近平面,此外我们还可以用垂直可视角度(field-of-view)fovY 和宽高比 aspect\_ratio 来表示。
[图片]
明显有:
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于