3D数学
[!important] 约定
本文以 DX12 使用的左手坐标系/行向量形式为主,使用其他标准会进行标注
左手坐标系/右手坐标系:注意左/右手定则
行向量/列向量:行向量右乘,列向量左乘
行向量:
$$\begin{array}
\
\begin{bmatrix}x & y & z\end{bmatrix}\begin{bmatrix}m_{11} & m_{12} & m_{13} \ m_{21} & m_{22} & m_{23} \ m_{31} & m_{32} & m_{33}\end{bmatrix}
\
=\begin{bmatrix}xm_{11}+ym_{21}+zm_{31} & xm_{12}+ym_{22}+zm_{32} & xm_{13}+ym_{23}+zm_{33}\end{bmatrix}\end{array}$$
列向量:
$$
\begin{bmatrix}m_{11}&m_{12}&m_{13}\ m_{21}&m_{22}&m_{23}\ m_{31}&m_{32}&m_{33}\end{bmatrix}\begin{bmatrix}x\ y\ z\end{bmatrix}=\begin{bmatrix}x m_{11}+ym_{12}+z m_{13}\ x m_{21}+ym_{22}+z m_{23}\ x m_{31}+ym_{32}+z m_{33}\end{bmatrix}
$$
- 为什么列向量作为很多学科的通用标准?因为列向量方程看起来更精简,行向量太宽了。
- 对于游戏编程,行向量更适合表示坐标空间变换,因为可以按顺序右乘,更具有可读性。
- 对于一个行向量 $\vec{v}$ 和三个变换矩阵 $ABC$ ,变换表示为 $\vec{v}ABC$,若将 $\vec{v}$ 转换为列向量,那么需要将 $ABC$ 分别转置后左乘,才可以表示相同的变换: $C^{\top}B^{\top}A^{\top}\vec{v}$
- 对于行向量:变换矩阵的行是基向量。对于列向量:变换矩阵的列是基向量
例如:
行向量的变换
$\begin{bmatrix}x & y & z\end{bmatrix}\begin{bmatrix}0&&3&&6\ 1&&4&&7\ 2&&5&&8\end{bmatrix}=x\begin{bmatrix}0 & 3 & 6\end{bmatrix}+y\begin{bmatrix}1 & 4 & 7\end{bmatrix}+z\begin{bmatrix}2 & 5 & 8\end{bmatrix}$
列向量的变换
$\begin{bmatrix}0&&1&&2\ 3&&4&&5\ 6&&7&&8\end{bmatrix}\begin{bmatrix}x \ y \ z\end{bmatrix}=x\begin{bmatrix}0\ 3\ 6\end{bmatrix}+y\begin{bmatrix}1\ 4\ 7\end{bmatrix}+z\begin{bmatrix}2\ 5\ 8\end{bmatrix}$
1 向量(矢量)
向量最基本的定义就是一个方向。或者更正式的说,向量有一个方向 (Direction)和大小 (Magnitude,也叫做强度或长度)。由于向量表示的是方向,起始于何处并不会改变它的值。下图我们可以看到向量 v 和 w 是相等的,尽管他们的起始点不同:
向量与标量运算
标量 (Scalar)只是一个数字(或者说是仅有一个分量的向量)。当把一个向量加/减/乘/除一个标量,我们可以简单的把向量的每个分量分别进行该运算。对于加法来说会像这样:
其中的+可以是+,-,·或÷,其中·是乘号。注意-和÷运算时不能颠倒(标量-/÷向量),因为颠倒的运算是没有定义的。
注意,数学上是没有向量与标量相加这个运算的,但是很多线性代数的库都对它有支持(比如说我们用的 GLM)。如果你使用过 numpy 的话,可以把它理解为 Broadcasting。
加减
点积 (dot product)
[!NOTE] 点积公式
代数定义: $$\mathbf{a}\cdot\mathbf{b}=\sum_{i=1}^n a_i b_i=a_1b_1+a_2b_2+\cdots+a_n b_n$$
几何定义: $$\mathbf{a}\cdot\mathbf{b}=|\mathbf{a}|\ |\mathbf{b}|\cos\theta$$
点积为 0,向量正交正交投影 (向量 a 落在向量 b 上的正交投影)
$$\mathbf p=proj_{b}(a)=||a||\cos{\theta}$$
叉积 (cross product)
[!NOTE] 叉积公式
代数定义,注意第二行的顺序:
$$\begin{bmatrix}x_1\ y_1\ z_1\end{bmatrix}\times\begin{bmatrix}x_2\ y_2\ z_2\end{bmatrix}=\begin{bmatrix}y_1z_2-z_1y_2\ z_1x_2-x_1z_2\ x_1y_2-y_1x_2\end{bmatrix}$$几何定义:c 是一个正交(垂直)于 a 和 b 的向量
$$c=a\times b$$叉积的大小=平行四边形面积:
$$||\mathbf{a}\times\mathbf{b}||,=,||\mathbf{a}||,||\mathbf{b}||,\sin\theta=两个边a和b形成的平行四边形的面积$$
颜色RGB运算
每款显示器所能发出的红、绿、蓝三色光的强度都是有限的。为了便于描述光的强度,我们常将量化为范围在 $0~1$ 归一化区间中的值。$0$ 代表无强度,$1$ 则表示强度最大,处于两者之间的值就表示应的中间强度。
例如,强度值 $(0.25,0.67,1.0)$ 就表明此光线由强度为 $25%$ 的红色光、强度为 $67%$ 的绿光以及强度为 $100%$ 的蓝色光混合而成。由此例可以看出,我们能用 3D 向量 $(r, g, b)$ 来表示颜色,其中 $0≤r, g, b≤1$,这 3 种颜色分量分别代表红、绿、蓝三色光在混合光中的强度。
颜色相加减获得新颜色:$(0.0,:0.5,:0)+(0,:0.0,:0.25)=(0.0,:0.5,:0.25)\quad\quad\text{}$
标量乘法:$0.5(1,1,1)=(0.5,:0.5,:0.5)\quad\quad$
分量式乘法(Modulation 或componentwise):
$\displaystyle(c_r,c_g,c_b)\otimes(k_r,k_g,k_b)=(c_r k_r,c_g k_g,c_b k_b)\quad\text{}$
这种运算主要应用于光照方程。例如,假设有颜色为 $( r, g, b)$ 的入射光线,照射到一个反射 $50%$ 红色光、7$5%$绿色光、$25%$蓝色光且吸收剩余光的表面。那么,我们就可以据此给出反射光线的颜色:
$(r,g,b)\otimes(0.5,0.75,0.25)=(0.5r,0.75g,0.25b)\quad\text{}$
在进行颜色运算的过程中,颜色分量有可能会超出$[0, 1]$这个区间。如,思考 $(1,0.1,0.6)+(0,0.3,0.5)=(1,0.4,1.1)$这个等式。由于 $1.0$ 代表颜色分量的最大强度,所以任何光的强度都不能超过此值。因此,我们就只得将值为 $1.1$ 的强度与 $1.0$ 这一上限强度视作等同,将 $1.1$ 钳制 ( clamp)为 $1.0$。同样地,显示器也不能发出强度为负值的光,所以亦应把负的颜色分量 (由减法运算所得到的结果)钳制为 $0.0$.
颜色相加是指光的叠加,物理上是光的强度相加。 例如多个光源照射到一佃表面后反射至摄像机,就可以把各固光照的反射结果相加。而题目中的例子是 Phong 或 Blinn 材质的反射模型,其意羲可以算是一棰凝合,把材質的反射分解成漫反射和镜面反射,然後把两反射光的结果相加。
颜色分量式相乘,应该理解颜色的非等比缩放。 例如,光通逼有色玻璃畤,玻璃吸收某百分比的红、蓝、绿,就可以把光的红蓝缘强度分别乘以对应的百分比。漫反射也可以理解成材質吸收了某百分比的入射光後向各方向反射。
如果考虞 HDR 的情况,光的颜色可以大於 1,但吸收率仍是 $[0,1]$。遣漾大概更不鲁混淆两律斓算。
规范化
normalize 的不同译法:标准化,归一化,规范化,规格化,单位化…… 译者按:区间、范围为归一化,名词向量或空间为规范化 (把一个向量的长度变为单位长度称为向量的规范化,方法是将向量的每个分量除以该向量的模,结果得到一个单位向量。
有一个特殊类型的向量叫做**单位向量 (Unit Vector)**。单位向量有一个特别的性质——它的长度是 1。我们可以用任意向量的每个分量除以向量的长度得到它的单位向量 $\hat{n}$:
$$:\hat{n}=\dfrac{\bar{v}}{||\bar{v}||}$$
正交化
如果向量集 $<!–swig0–> }$ 中的每个向量都是互相正交且皆具单位长度,那么我们就称此集合是**规范正交 (orthonormal)的。
2D 正交化:假设我们有向量集合 ${v_0,v_1}$ ,现欲将它正交化为图 1.11 中所示的正交集 ${w_0, w_1}$。首先设 ${w_0=v_0}$, 通过使 $v_1$ 减去它在 $w_0$ 上的分量(投影)来令它正交于 $w_0$ :
$$w_1=v_1-proj_{w_0} (v_1)$$
此时得到了元素相互正交的向量集合 ${w_0,w_1 }$ ,最后将其规范化为单位向量即可。
3D 正交化方法类似,这种方法比较麻烦,我们可以采用更通用的方法,即格拉姆-施密特 (Gram-Schmidt Orthogonalization)正交化(以下简称施密特正交化)。
施密特正交化
[!NOTE] 计算方法
如果向量组 $\alpha_1,\alpha_2,\alpha_3$ 线性无关,令
$$
\begin{array}{l}
\boldsymbol{\beta}_{1}=\boldsymbol{\alpha}{_1}:,\
\boldsymbol{\beta}_2:=:\boldsymbol{\alpha}_2-\frac{(\boldsymbol{\alpha}_2:,\boldsymbol{\beta}_1)}{(\boldsymbol{\beta}_1:,\boldsymbol{\beta}_1)}\boldsymbol{\beta}_1\
\boldsymbol{\beta}_3:=:\boldsymbol{\alpha}_3-\frac{(\boldsymbol{\alpha}_3:,\boldsymbol{\beta}_1:)}{(\boldsymbol{\beta}_1:,\boldsymbol{\beta}_1:)}\boldsymbol{\beta}_1-\frac{(\boldsymbol{\alpha}_3:,\boldsymbol{\beta}_2:)}{(\boldsymbol{\beta}_2:,\boldsymbol{\beta}_2:)}\boldsymbol{\beta}_2:,
\end{array}
$$
那么 $\beta_1,\beta_2,\beta_3$ 两两正交,称为正交向量组,将其规范化,有 $$
\boldsymbol{\gamma}_1=\dfrac{\boldsymbol{\beta}_1}{|\boldsymbol{\beta}_1|},\boldsymbol{\gamma}_2=\dfrac{\boldsymbol{\beta}_2}{|\boldsymbol{\beta}_2|},\boldsymbol{\gamma}_3=\dfrac{\boldsymbol{\beta}_3}{|\boldsymbol{\beta}_3|},$$完成由 $\alpha 到 \gamma$ 的施密特正交化。
基本步骤:设 ${w_0=v_0}$
对于 $1\leqslant i\leqslant-1$,
令 $w_i=\nu_i-\sum_{j=0}^{i-1}\text{proj}_{w_j}(v_i)$
规范化:令 $w_i=\frac{w_i}{\parallel w_i\parallel}$
从直观上来说,在将给定集合内的向量添加到规范正交集中时,我们需要令减去它在现有规范正交集中其他向量 ${w_0, w_1,…, w_{i-1}}$ 方向上的分量(投影),这样方可确保新加入规范正交集的向量与该集合中的其他向量互相正交。
通过叉积正交化
[!NOTE] 通过叉积正交化
令 $w_0=\frac{\nu_0}{|\nu_0|}$
令 $w_2=\frac{w_0\times w_1}{\parallel w_0\times w_1}$
令 $w_1=w_2\times w_0$
由于 ${w}{2}\perp w{0}$,且 $||w_2||=||w_1||=1$,因此 $||w_2\times w_0||=1$ ,所以结果已经是规范化的。
此时 ${w_0,w_1,w_2 }$ 是规范正交的。
在上面的示例中,我们首先令 $w_0=\frac{\nu_0}{|\nu_0|}$,这意味着将向量 $v_0$ 转换到向量 $w_0$ 时并未改变方向,仅缩放了的长度。但是,向量 $w1$ 与向量 $w2$ 的方向却可以分别不同于 $v_1$ 和向量 $v_2$ 。对于特定的应用来说,不改变集合中某个向量的方向也许是件很重要的事。
例如,龙书中利用 3 个规范正交向量 ${v_0, v_1, v_2}$ 来表示摄像机(camera)的朝向,而其中的第三个向量 $v_2$ 描述的正是摄像机的观察方向。在对这些向量进行正交化处的过程中,我们通常并不希望改变此摄像机的观察方向。所以,我们会运用上面的算法,在第一步中处理向量 $v_2$,再通过修改向量 $v_0$ 和向量 $v_1$ 来使它们正交化。
2 变换矩阵
1 旋转
首先我们来定义一个向量的旋转到底是什么。2 D 或 3 D 空间中的旋转用角 (Angle)来表示。角可以是角度制或弧度制的,周角是 360 角度或 2π弧度。我个人更喜欢用角度,因为它们看起来更直观。
大多数旋转函数需要用弧度制的角,但幸运的是角度制的角也可以很容易地转化为弧度制的:
- 弧度转角度:
角度 = 弧度 * (180.0f / PI)
- 角度转弧度:
弧度 = 角度 * (PI / 180.0f)
PI
约等于 3.14159265359。
旋转矩阵是正交矩阵:转置矩阵=逆矩阵
[!attention]
行向量和列向量形式互为转置
二维矩阵旋转
推导: [[01 三维旋转#1.1 2D旋转]]
行向量
$\left[\begin{array}{cc}\cos\theta&\sin\theta\ -\sin\theta&\cos\theta\end{array}\right]$列向量
$\left[\begin{array}{cc}\cos\theta&-\sin\theta\ \sin\theta&\cos\theta\end{array}\right]$
三维旋转矩阵
沿 x 轴旋转
- 行向量
$\begin{bmatrix}1&0&0&0\ 0&\cos\theta&\sin\theta&0\ 0&-\sin\theta&\cos\theta&0\ 0&0&0&1\end{bmatrix}$ - 列向量
$\begin{bmatrix}1&0&0&0\ 0&\cos\theta&-\sin\theta&0\ 0&\sin\theta&\cos\theta&0\ 0&0&0&1\end{bmatrix}$
沿 y 轴旋转
- 行向量
$\begin{bmatrix}\cos\theta&0&-\sin\theta&0\ 0&1&0&0\ \sin\theta&0&\cos\theta&0\ 0&0&0&1\end{bmatrix}$ - 列向量
$\begin{bmatrix}\cos\theta&0&\sin\theta&0\ 0&1&0&0\ -\sin\theta&0&\cos\theta&0\ 0&0&0&1\end{bmatrix}$
沿 z 轴旋转
行向量
$\begin{bmatrix}\cos\theta&\sin\theta&0&0\ -sin\theta&\cos\theta&0&0\ 0&0&1&0\ 0&0&0&1\end{bmatrix}$列向量
$\begin{bmatrix}\cos\theta&-\sin\theta&0&0\ \text{sin}\theta&\cos\theta&0&0\ 0&0&1&0\ 0&0&0&1\end{bmatrix}$
可以将多个矩阵复合,比如先沿着 x 轴旋转再沿着 y 轴旋转。但是这会很快导致一个问题——万向节死锁(Gimbal Lock),对于 3 D 空间中的旋转,一个更好的模型是沿着任意的一个轴,比如单位向量 $(0.662, 0.2, 0.7222)$ 旋转,而不是对一系列旋转矩阵进行复合。
沿任意轴旋转
罗德里格斯公式
$\quad(R_x,R_y,R_z)\text{,}$ 表示任意旋转轴
- 行向量
$$
\begin{bmatrix}{R_x}^2\left(1-\cos\theta\right)+\cos\theta&R_x R_y\left(1-\cos\theta\right)+R_z\sin\theta&R_x R_z\left(1-\cos\theta\right)-R_y\sin\theta & 0\ R_x R_y\left(1-\cos\theta\right)-R_z\sin\theta&{R_y}^2\left(1-\cos\theta\right)+\cos\theta&R_y R_z\left(1-\cos\theta\right)+R_x\sin\theta & 0\ R_x R_z\left(1-\cos\theta\right)+R_y\sin\theta&R_y R_z\left(1-\cos\theta\right)-R_x\sin\theta&{R_z}^2\left(1-\cos\theta\right)+\cos\theta & 0 \ 0 & 0 & 0 & 1\end{bmatrix}
$$ - 列向量
$$
\begin{bmatrix}{R_x}^2(1-\cos\theta)+\cos\theta&R_x R_y(1-\cos\theta)-R_z\sin\theta&R_xR_z(1-\cos\theta)+R_y\sin\theta&0\ R_y R_x(1-\cos\theta)+R_z\sin\theta&{R_y}^2(1-\cos\theta)+\cos\theta&R_y R_z(1-\cos\theta)-R_x\sin\theta&0\ R_z R_x(1-\cos\theta)-R_y\sin\theta&R_z R_y(1-\cos\theta)+R_x\sin\theta&{R_z}^2(1-\cos\theta)+\cos\theta&0\ 0&0&0&1\end{bmatrix}
$$
欧拉角
[[01 三维旋转#欧拉角]]
四元数
[[01 三维旋转#四元数]]
2 缩放
[!attention]
缩放矩阵因为是对角矩阵,转置相等。所以行向量、列向量形式一致
2D 缩放
$\begin{bmatrix}S_x & 0 \ 0 & S_y\end{bmatrix}$
3D 缩放
$\begin{bmatrix}S_x&0&0&0\ 0&S_y&0&0\ 0&0&S_z&0\ 0&0&0&1\end{bmatrix}$
任意方向缩放
3D 数学 P128
3 平移
行向量
$\begin{bmatrix}x&y&z&1\end{bmatrix}\begin{bmatrix}1&0&0&0\ 0&1&0&0\ 0&0&1&0\ \Delta x&\Delta y&\Delta z&1\end{bmatrix}=\begin{bmatrix}x+\Delta x&y+\Delta y&z+\Delta z&1\end{bmatrix}$
列向量:
$\begin{bmatrix}1&0&0&\Delta x\ 0&1&0&\Delta y\ 0&0&1&\Delta z\ 0&0&0&1\end{bmatrix}\cdot\begin{bmatrix}x\ y\ z\ 1\end{bmatrix}=\begin{bmatrix}x+\Delta x\ y+\Delta y\ z+\Delta z\ 1\end{bmatrix}$
4 镜像(反射)
[!attention]
以下矩阵为行向量形式
又称反射,是一种围绕直线 (2D)或平面(3D)翻转对象的变换
绕任意轴镜像(2D)
设 $\vec n$ 是二维单位矢量。围绕穿过原点并垂直于 $\vec n$ 的反射轴来执行反射的矩阵:
$\begin{bmatrix}1-2n_x^2&-2n_xn_y\-2n_xn_y&1-2n_y^2\end{bmatrix}$
绕任意平面镜像(3D)
为了变换为线性,平面必须包含原点
$\left[\begin{array}{ccc}1-2n_{x}{}^2&-2n_{x}n_{y}&-2n_{x}n_{z}\ -2n_{x}n_{y}&1-2n_{y}{}^2&-2n_{y}n_{z}\ -2n_{x}n_{z}&-2n_{y}n_{z}&1-2n_{z}{}^2\end{array}\right]$
5 错切
[!attention]
以下矩阵为行向量形式
错切 (Shearing)是一种“倾斜”坐标空间的变形,它将不均匀地拉伸坐标空间,不保留角度。然而,令人惊讶的是,面积和体积却保留了。其基本思路是将一个坐标的倍数添加到另一个坐标上。例如,在二维中,可以取 y 的倍数并将其添加到 x 上,以便 x’=x +sy。图 5.10 显示了这个例子。
错切是一种很少使用的变换,它也被称为倾斜变形 (Skew Transform)。结合错切和缩放(均匀或不均匀)会产生一种变形效果,使人分不清它是否包含了旋转和非均匀缩放的变换。
2D 错切
${H}_x(s)$ 表示 x 坐标被另一个坐标 y 错切;参数 s 控制错切的方向和量
$\mathbf{H}_x(s)=\left[\begin{array}{cc}1&0\ s&1\end{array}\right]\quad$
$\mathbf{H}_y(s)=\left[\begin{array}{cc}1&s\ 0&1\end{array}\right]$
3D 错切
在三维中,我们可以采用一个坐标并将该坐标的不同倍数添加到另外两个坐标上。符号 $H_{xy}$ 表示 $x$ 坐标和 $y$ 坐标按照另一个坐标 $z$ 移动。完整的矩阵如下:
$\mathbf{H}_{xy}(s,t)=\left[\begin{array}{ccc}1&0&0\ 0&1&0\ s&t&1\end{array}\right]$
$\mathbf{H}_{xz}(s,t)=\left[\begin{array}{ccc}1&0&0\ s&1&t\ 0&0&1\end{array}\right]$
$\mathrm{H}_{yz}(s,t)=\left[\begin{array}{ccc}1&s&t\ 0&1&0\ 0&0&1\end{array}\right]$
6 复杂变换
引入齐次矩阵之后,可以方便地做以下更一般性的仿射变换
- 围绕不穿过原点的轴旋转。
- 围绕不穿过原点的平面进行缩放。
- 围绕不穿过原点的平面反射。
- 在不穿过原点的平面上进行正交投影。
基本思想:将变换的“中心”平移到原点,然后线性变换, 最后将中心平移回原始位置。
最终仿射变换矩阵为 $T(-c)R(\alpha)T(c)$,平移矩阵 $T(-c)$ 和 $T(c)$ 具有相反的平移量
7 变换的分类
线性变换
- 可以通过矩阵乘法实现的任何变换都是线性变换。
- 线性变换不包含平移。
仿射变换
- 仿射变换=线性变换+平移
- 矩阵没有交换律:同时需要线性变换和平移的时候,需要先线性变换再平移
- 顺序:先缩放,后旋转,再位移
可逆变换
- 平移的可逆变换通过平移相反的数量实现
- 线性变换的可逆变换通过逆矩阵实现
- 除了投影之外所有原始变换都是可逆的,因为投影丢弃了一个或多个维度的信息。
保持角度的变换
- 如果两个矢量之间的角度在变换后的大小或方向上没有改变,则该变换就是保持角度的。
- 只有平移、旋转和均匀缩放才是保持角度的变换。
- 所有保持角度的变换都是仿射和可逆的。
正交变换
平移、旋转和反射都只有正交变换
所有正交变换都是仿射和可逆的。
正交矩阵将保留角度、面积和体积的大小,但其符号却可能不一样(反射可能改变角度)。
正交矩阵的行列式为 $\pm1$
刚体变换
- 刚体变换(Rigid Body Transformation)是指改变对象的位置和方向但不改变其形状的变换。
- 保留所有角度、长度、面积和体积。
- 平移和旋转都是刚体转换,但是反射则不被认为是严格的刚体变换。
- 刚体变换也称为合适变换(Proper Transformation)。所有刚体变换都是正交的、保持角度的、可逆的和仿射的。刚体变换是本节中讨论的最严格的变换类,但它们在实践中也非常常见。
- 任何刚体变换矩阵的行列式均为 1。
3 齐次矩阵(仿射变换矩阵)
引入齐次坐标
先讨论二维的仿射变换:
线性变换一般形式如下:
$\begin{bmatrix}x’ & y’\end{bmatrix}=\begin{bmatrix}x & y\end{bmatrix}\begin{bmatrix}a & b \ c & d\end{bmatrix}$
由于平移不是线性的,所以涉及平移的仿射变换不能用一个矩阵来完成变换:
$\begin{bmatrix}x’ & y’\end{bmatrix}=\begin{bmatrix}x & y\end{bmatrix}\begin{bmatrix}a & b \ c & d\end{bmatrix}+\begin{bmatrix}t_x & t_y\end{bmatrix}$ $\begin{bmatrix}a & b \ c & d\end{bmatrix}$ 表示线性变换矩阵
不符合线性变换的形式,多加了 $\begin{bmatrix}t_x & t_y\end{bmatrix}$,我们不希望它搞特殊,我们试图找到一种方法统一线性变换和仿射变换的形式,由此引入齐次坐标。
齐次坐标就是将一个原本是 n 维的向量用一个 n+1 维向量来表示,简单地说就是多了一个 $w$ 分量。
- 点的 w 坐标为 1:$(x , y, 1)$
- 向量的 w 坐标为 0 :$(x, y, 0)$
最终形式如下:
$\begin{bmatrix}x’ & y’ & 1\end{bmatrix}=\begin{bmatrix}x & y & 1\end{bmatrix}\begin{bmatrix}a & b & 0\ c & d & 0 \ t_x & t_y & 1\end{bmatrix}$
对于二维中的齐次坐标 $(x, y, w)$ ,
想象一下,在三维中 $w= 1$ 处的标准二维平面,实际的二维点 $(x, y)$ 用齐次坐标表示为 $(x, y, 1)$,对于那些不在 w=1 平面上的点,则可以通过除以 $w$,将它们投影到 w=1 平面上,从而计算相应的二维点。这样,齐次坐标 $(x, y, w)$ 就可以映射到实际的二维点 $(x/w, y/w)$
综上,我们认为形如 $(x, y, w),w\neq0$ 的齐次坐标都表示点 $\displaystyle(\frac{x}{w}, \frac{y}{w}, 1)$
3D 齐次坐标
由以上引申出 3D 齐次坐标,将三维扩充至思维,总体思路一致。
形如 $(x, y,z, w),w\neq0$ 的齐次坐标都表示点 $\displaystyle(\frac{x}{w}, \frac{y}{w}, \frac{z}{w},1)$
齐次矩阵(又称仿射变换矩阵): $\begin{bmatrix}x’ & y’ &z’ & 1\end{bmatrix}=\begin{bmatrix}x & y & z & 1\end{bmatrix}\begin{bmatrix}a & b & c& 0\ d & e & f & 0 \ g & h & i & 0\ t_x & t_y & t_z & 1\end{bmatrix}$
$\begin{bmatrix}a & b &c\ d & e & f \ g & h & i \end{bmatrix}$ 表示线性变换矩阵,$t_x,t_y,t_z,$ 是平移量
[!summary] 总结:齐次坐标的作用
区分向量和点,点的 w 坐标为 1,向量的 w 坐标为 0 。更进一步,我们认为形如 $(x, y,z, w),w\neq0$ 的齐次坐标都表示点 $\displaystyle(\frac{x}{w}, \frac{y}{w}, \frac{z}{w},1)$
统一线性变换和仿射变换的计算方式,使用一个矩阵即可完成变换。
保证向量的平移不变性:可以发现只有线性变换部分会影响向量,平移部分不会影响,也就是说向量不会发生平移变换。
$\begin{bmatrix}x & y & z & 0\end{bmatrix}\begin{bmatrix}a & b & c& 0\ d & e & f & 0 \ g & h & i & 0\ 0 & 0 & 0 & 1\end{bmatrix}=\begin{bmatrix}x & y & z & 0\end{bmatrix}\begin{bmatrix}a & b & c& 0\ d & e & f & 0 \ g & h & i & 0\ t_x & t_y & t_z & 1\end{bmatrix}$保证两点之差得到的是一个向量,点与向量之和得到是一个点
$q-p=(q_{x},q_{y},q_{z},1)-(p_{x},p_{y},p_{z},1)=(q_x-p_x,q_y-p_y,q_z-p_z,0)$
$p+\vec{v}=\left(p_{x},p_{y},p_{z},1\right)+\left(\nu_x,\nu_y,\nu_z,0\right)=\left(p_x+\nu_x,:p_y+\nu_{y_1}:p_z+\nu_z,:1\right)$齐次除法计算透视投影 ^qctphb
几何意义
设 $t$ 为描述物体旋转操作的旋转变换,而 $b$ 为定义物体平移操作的平移向量。那么,该变换就可以用仿射变换来表示:
$\alpha(x,y,z)=\tau(x,y,z)+b=x\tau(i)+y\tau(j)+z\tau(k)+b\quad\text{}$
采用齐次坐标,上式写为:
$[x,y,z,w]\begin{bmatrix}\leftarrow\tau(i)\rightarrow\ \leftarrow\tau(j)\rightarrow\ \leftarrow\tau(k)\rightarrow\ \leftarrow b\rightarrow\end{bmatrix}=[x’,y’,z’,w]$
至此,为了理解此方程的几何意义,我们还要将知阵中的行向量依次绘制出来(见图 3.7)。我们能看到 $\tau$ 仅将标准基向量 $i,j , k$,分别旋转到对应的新方向 $\tau (i),\tau (j), \tau (k)$。而向量 $b$ 则是一个位置向量,它表示物体相对于原点的位移。现在来看图 3.7,它以几何学的角度展示了如何通过计算 $\alpha(x,y,z)=x\tau(i)+y\tau(j)+z\tau(k)+b$ 来求取变换后的点。
这种思路同样可以运用在缩放或斜切变换上。请考虑这样一种线性变换 $\tau$ ,它将图 3.8 所示的正方形拉扯为一个平行四边形。斜切处理后的点即为斜切变换后的基向量
4 投影
透视投影
正交投影
[!attention]
以下矩阵为行向量形式
投影到主轴或主平面
投影到主轴(2D)
主轴指 $xy$ 坐标轴
$\mathbf P_x=\mathbf S\left(\begin{bmatrix}0&1\end{bmatrix},0\right)=\left[\begin{array}{cc}1&0\ 0&0\end{array}\right]$
$\mathbf P_y=\mathbf S\left(\begin{bmatrix}1&0\end{bmatrix},0\right)=\left[\begin{array}{cc}0&0\ 0&1\end{array}\right]$
投影到主平面(3D)
主平面指 $xyz$ 坐标形成的面
$\mathbf P_{xy}=\mathbf S\left(\begin{bmatrix}0&0&1\end{bmatrix},0\right)=\left[\begin{array}{ccc}1&0&0\ 0&1&0\ 0&0&0\end{array}\right]$
$\mathbf{P}_{xz}=\mathbf{S}\left(\begin{bmatrix}0&1&0\end{bmatrix},0\right)=\left[\begin{array}{ccc}1&0&0\ 0&0&0\ 0&0&1\end{array}\right]$
$\mathbf{P}_{yz}=\mathbf{S}\left(\begin{bmatrix}1&0&0\end{bmatrix},0\right)=\begin{bmatrix}0&0&0\ 0&1&0\ 0&0&1\end{bmatrix}$
投影到任意线或平面
$\vec{n}$ 垂直于投影的线或面
投影到任意线(2D)
$\left[\begin{array}{c c}1-n_{x}{}^{2}&-n_{x}n_{y}\ -n_{x}n_{y}&1-n_{y}{}^{2}\end{array}\right]$
投影到任意平面(3D)
$\left[\begin{array}{ccc}1-n_{x}{}^{2}&-n_{x}n_{y}&-n_{x}n_{z}\ -n_{x}n_{y}&1-n_{y}{}^{2}&-n_{y}n_{z}\ -n_{x}n_{z}&-n_{y}n_{z}&1-n_{z}{}^{2}\end{array}\right]$
5 视图变换
[[02 空间变换]]
6 球坐标系
球坐标 $(r,\theta,\beta)$ 表示一个点 $P$ 在三维空间的位置
$r$:原点与点 $P$ 之间的“径向距离”
$θ$:原点到点 $P$ 的连线与正 $y$ 轴之间的“极角”
$\beta$:原点到点 $P$ 的连线在 $xz$ 平面的投影线与正 $x$ 轴之间的“方位角”
笛卡尔坐标 -> 球面坐标
已知一个点的笛卡尔坐标 $P(x,y,z)$,转换到球坐标系 $(r,\theta,\beta)$
则
$$r = \sqrt{x^2+y^2+z^2}$$
$$\theta = \arccos{\frac{z}{r}}$$
$$\beta = \arctan{\frac{y}{x}}$$
球面坐标->笛卡尔坐标
球坐标系 $(r,\theta,\beta)$ 与直角坐标系 $(x, y, z)$ 的转换关系:
$\begin{cases}x=rsinθcos\beta\\y=rsinθsin\beta\\z=rcosθ\end{cases}$
$\theta$ 角在下方的情况:把图中的 $\vec{a}$ 换成半径 $r$ 即可 :
![[01 三维旋转#推导]]