《Fundamentals of Computer Graphics》2. Miscellaneous Math

集合与映射

映射与函数(Function)是一回事

  • $\mathbb R$:实数集
  • $\mathbb R^+$:非负实数集(包括 $0$)
  • $\mathbb R^2$:实二维平面的有序对集合
  • $\mathbb R^n$:笛卡尔空间(二维直角坐标系构成的空间)中的 n 维点集
  • $\mathbb Z$:整数
  • $S^2$:单位球面的三维点集(是 $\mathbb R^3$ 的子集)

$S^2$ 可以映射到二维表面上,所以它可以由二维表示(向量组的秩是 2)

$f: \mathbb R\mapsto\mathbb{Z}$ 是一个映射,左边称为定义域(domain),右边称值域(target),$f(a)$ 称为 $a$ 的像(image)

反函数、双射(正反映射均唯一)

三角函数

三角函数、弧度、角度、反三角(尤其是 atan2: $\mathbb R^2\mapsto[-\pi, \pi]$)、三角公式

image-20241015202118620

面积公式:

$$ S=\frac{1}{4}\sqrt{(a+b+c)(-a+b+c)(a-b+c)(a+b-c)} $$

大圆(单位球上的中心点在原点的圆弧)、球面三角函数(边都在大圆上的三角形)

立体角:平面角的定义是二维线条投影到单位圆上(线条上的点与圆心的连线与单位圆的交点集合)的长度大小,度量是 $2\pi$;立体角则是提升到了三维,是三维物体投影到单位球上的面积大小,度量是 $4\pi$

向量

向量、向量计算、点积、映射(用 $\vec{a}\rightarrow \vec{b}=\Vert \vec{a}\Vert \cos \phi=\frac{\vec{a}·\vec{b}}{\Vert \vec{b}\Vert }$ 表示)、叉乘(仅三维)、正交基、坐标系

从单个向量创建坐标系

从单个向量 $\vec{a}$ 创建局部坐标系:

$$ \vec{w}=\frac{\vec{a}}{\Vert \vec{a}\Vert }\\ \vec{u}=\frac{\vec{t}\times\vec{w}}{\Vert \vec{t}\times\vec{w}\Vert }\\ \vec{v}=\vec{w}\times\vec{u} $$

从两个向量创建坐标系

从两个向量 $\vec{a}$(表示 $\vec{w}$,相机朝向)和 $\vec{b}$(表示 $\vec{v}$,指定相机的旋转)创建局部坐标系,通常只需要叉乘即可,但为了确保正交,鼓励再执行一遍从单个向量创建坐标系的流程,即:

$$ \vec{w}=\frac{\vec{a}}{\Vert \vec{a}\Vert }\\ \vec{u}=\frac{\vec{b}\times\vec{w}}{\Vert \vec{b}\times\vec{w}\Vert }\\ \vec{v}=\vec{w}\times\vec{u} $$

这个方法非常有效,即使 $\vec{b}$ 与 $\vec{a}$ 不垂直,得到的 $\vec{v}$ 也是与 $\vec{b}$ 最接近的垂直于 $\vec{w}$ 的向量。

如果 $\vec{a}$ 与 $\vec{b}$ 共线,那么这个方法不能工作,叉乘是 $\vec{0}$

整理正交基

如果从精度较低的文件中读取正交基,可能会出现些微的误差,这时需要重新整理正交基。可以使用上面的方法,但上面的方法“偏爱” $\vec{w}$,因为 $\vec{w}$ 的方向始终准确,这就不太好。之后有一个叫 SVD 的方法来解决这个问题

积分

图形学中大多积分不需要解析解,且有明确的含义

平均和加权平均

关于立体角的积分(这个这边写的太晦涩了,看不懂积分式子,后面章节还会看到它)

(概率)密度函数

曲线和曲面

tips:尽量使用向量形式,包括代码上(例如圆的表示,不要用 $x$、$y$、$z$,而直接用向量)

隐式 2D 曲线:$f(x, y)=0$。梯度与法线向量(具体在《方向导数、梯度和法线向量》这一个笔记中):$\nabla f(x,y)=\left(\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}\right)$

隐式 2D 直线:$Ax+By+C=0$。距离:$\text{distance}=\frac{f(a,b)}{\sqrt{A^2+B^2}}$,一般会将 $A$ 和 $B$ 归一化

隐式二次曲线:$Ax^2+Bxy+Cy^2+Dx+Ey+F=0$,圆和椭圆

3D 隐式曲面:$f(x,y,z)=0$,向量形式 $f(\vec p)=0$。法线为 $\vec n=\nabla f(\vec p)=\left(\frac{\partial f(\vec p)}{\partial x},\frac{\partial f(\vec p)}{\partial y},\frac{\partial f(\vec p)}{\partial z}\right)$,指向 $f(\vec p)>0$ 的一侧

隐式平面:$(\vec p-\vec a)\cdot\vec n=0$(点法式),将 $\vec n$ 取代为平面内的两个向量叉乘后得到隐式方程 $(\vec p-\vec a)\cdot((\vec b-\vec a)\times(\vec c-\vec a))=0$ (三点求平面),将这个式子表示成行列式:

$$ \left|\begin{matrix} x-x_a & y-y_a & z-z_a \\ x_b-x_a & y_b-y_a & z_b-z_a \\ x_c-x_a & y_c-y_a & z_c-z_a \\ \end{matrix}\right|=0 $$

3D 二次曲面:球体可以写成 $f(\vec p)=(\vec p-\vec c)-r^2$,椭圆球。

从隐式曲面得到三维曲面:两个曲面的交线

2D 参数曲线:$\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}g(t)\\f(t)\end{bmatrix}$,写成向量形式为 $\vec p=f(t)$

2D 参数直线:$\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}x_0+t(x_1-x_0)\\y_0+t(y_1-y_0)\end{bmatrix}$,向量形式为 $\vec p(t)=\vec {p_0}+t(\vec {p_1}-\vec {p_0})$,也可以写成 $\vec p(t)=\vec {o}+t\vec d$(源点和距离向量),当 $\vec d$ 为单位向量时,这个曲线是被弧长参数化的(不理解这个概念)

2D 参数圆:$\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}x_c+r\cos\phi\\y_c+r\sin\phi\end{bmatrix}$($\phi$ 的取值范围为任意一个长度为 $\pi$ 的半开区间,如 $(0,2\pi]$),椭圆曲线即 $\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}x_c+a\cos\phi\\y_c+b\sin\phi\end{bmatrix}$。

3D 参数曲线:$\begin{bmatrix}x\\y\\z\end{bmatrix}=\vec p(t)$

3D 参数直线:$\vec p=\vec o+t\vec d$

3D 参数曲面:$\begin{bmatrix}x\\y\\z\end{bmatrix}=\vec p(u, v)$,例如球的表达式为 $\begin{bmatrix}x\\y\\z\end{bmatrix}=\begin{bmatrix}r\cos\phi\sin\theta\\r\sin\phi\sin\theta\\r\cos\theta\end{bmatrix}$。固定一个参数的形成的曲线称为等参曲线(如 $\vec q(t)=\vec p(t, v_0)$ 固定 $v$ 为 $v_0$),等参曲线 $\vec q(t)$ 对 $t$ 的导函数 $\vec{q}^{'}(t)$ 描述了切线,把它记作 $\vec {p_u}$,把固定 $u$ 的曲线导数记作 $\vec{p_v}$,可得 法向量 $\vec u=\vec{p_u}\times\vec{p_v}$,规定这个方向为外侧

总结:

  • 隐式曲线、隐式曲面:$f:\mathbb R^2\mapsto\mathbb{R}$ 或 $f:\mathbb R^3\mapsto\mathbb{R}$,$S=\{\vec p|f(\vec p)=0\}$,梯度给出法向量,切向量由前面构造正交基的方法得到
  • 2D 和 3D 参数曲线:$\vec p:D\subset \mathbb R\mapsto\mathbb{R}^2$ 或 $\vec p:D\subset \mathbb R\mapsto\mathbb{R}^3$,$S=\{\vec p(t)|t\in D\}$,导函数给出切向量,法向量由前面构造正交基的方法得到
  • 参数曲面:$\vec p:D\subset \mathbb R^2\mapsto \mathbb R^3$,$S=\{\vec p(u,v)|(u,v)\in D\}$,导函数给出切向量,法向量由前面构造正交基的方法得到
  • 3D 直线没有隐式的形式

线性插值

线性插值:$\vec p=(1-t)\vec a+t\vec b$,其中 $t\in[0,1]$

一组位置 $(x_0,y_0),(x_1,y_1),...,(x_n,y_n)$ 的线性插值:之间通过直线相连,参数 $t=\frac{x-x_i}{x_{i-1}-x_i}$,得到 $f(x)=y_i+\frac{x-x_i}{x_{i-1}-x_i}(y_{i+1}-y_i)$

三角形

三角形是图元的基础,颜色等信息会标记到三角形顶点上,重心坐标系

2D 三角形

2D 三角形面积(顺时针为负号,逆时针为正号):

$$ A =\frac{1}{2} \left|\begin{matrix} x_b-x_a & x_c-x_a \\ y_b-y_a & y_c-y_a \\ \end{matrix}\right| $$

重心坐标系:把点 $A$ 当做原点,$\overrightarrow {AB}$ 和 $\overrightarrow {AC}$ 当做(非正交)基构建的坐标系。在这个坐标系中,任何点都可以写成:

$$ \vec p=\vec a+\beta(\vec b-\vec a)+\gamma(\vec c -\vec a) $$

可以展开:

$$ \vec p=(1-\beta-\gamma)\vec a+\beta\vec b+\gamma\vec c $$

人们通常会令 $\alpha=1-\beta-\gamma$ 从而写成一个对称的形式:

$$ \vec p(\alpha,\beta,\gamma)=\alpha\vec a+\beta\vec b+\gamma\vec c $$

这个重心坐标系有一个好处,就是:

  • 当 $\alpha$、$\beta$、$\gamma$ 都在 $(0,1)$ 范围内时,点 $\vec p$ 位于三角形内部(不包括边)
  • 当 $\alpha$、$\beta$、$\gamma$ 其中一个为 $0$,另外两个在 $(0,1)$ 范围内时,点 $\vec p$ 位于三角形的边上(不包括顶点)
  • 当 $\alpha$、$\beta$、$\gamma$ 其中两个为 $0$,其余一个为 $1$ 时,点 $\vec p$ 位于三角形的顶点上

笛卡尔坐标系转换到重心坐标系:

作平行线,例如对于 $\beta$ 来说,作 $AC$ 这条边的平行线,过 $A$ 点的平行线 $\beta=0$,过 $B$ 点的平行线 $\beta=1$,在某条平行线上的点的 $\beta$ 值相等,并且 $\beta$ 与该距离成正比关系,所以:

$$ \beta=\frac{f_{ac}(x,y)}{f_{ac}(x_b,y_b)}=\frac{(y_b-y_a)x+(x_b-x_a)y+x_ay_b-x_by_a}{(y_b-y_a)x_b+(x_b-x_a)y_b+x_ay_b-x_by_a} $$

同理:

$$ \gamma=\frac{f_{ab}(x,y)}{f_{ab}(x_c,y_c)}=\frac{(y_c-y_a)x+(x_c-x_a)y+x_ay_c-x_cy_a}{(y_c-y_a)x_c+(x_c-x_a)y_c+x_ay_c-x_cy_a} $$

然后:

$$ \alpha=1-\beta-\gamma $$

image-20241016224144474

一个更简洁的计算方式是用面积,底相同,高(距离)与面积成比例:

$$ \alpha=A_a/A\\ \beta=A_b/A\\ \gamma=A_c/A $$

image-20241016224020288

可以发现:

$$ A_a+A_b+A_c=A $$

image-20241016224039464

3D 三角形

2D 可以完美延伸到 3D,所以仍然使用:

$$ \vec p(\alpha,\beta,\gamma)=\alpha\vec a+\beta\vec b+\gamma\vec c\\ \alpha=1-\beta-\gamma $$

除此之外,法向量可以由叉积得到:

$$ \vec n=(\vec b-\vec a)\times(\vec c-\vec a) $$

三角形的面积可以由叉积的长度来计算:

$$ A=\frac{1}{2}\Vert (\vec b-\vec a)\times(\vec c-\vec a)\Vert =\frac{1}{2}\Vert \vec n\Vert $$

既然如此,上面我们知道了 $A_a$、$A_b$、$A_c$、$A$ 与 $\alpha$、$\beta$、$\gamma$ 的关系,我们可以计算出各自的面积:

$$ A=\frac{1}{2}\Vert \vec n\Vert \\ A_a=\frac{1}{2}\Vert \vec {n_a}\Vert \\ A_b=\frac{1}{2}\Vert \vec {n_b}\Vert \\ A_c=\frac{1}{2}\Vert \vec {n_c}\Vert $$

其中:

$$ \vec {n_a}=(\vec c-\vec b)\times(\vec p-\vec b)\\ \vec {n_b}=(\vec a-\vec c)\times(\vec p-\vec c)\\ \vec {n_c}=(\vec b-\vec a)\times(\vec p-\vec a)\\ $$

那么:

$$ \alpha=\frac{\Vert \vec {n_a}\Vert }{\Vert \vec n\Vert }\\ \beta=\frac{\Vert \vec {n_b}\Vert }{\Vert \vec n\Vert }\\ \gamma=\frac{\Vert \vec {n_c}\Vert }{\Vert \vec n\Vert } $$

考虑到 $\vec a\cdot \vec b=\Vert \vec a\Vert\Vert \vec b\Vert \cos \phi$,而根据向量同向还是反向,$\cos\phi$ 取值为 $\pm 1$,可以扩展到三角形外的情况:

$$ \alpha=\frac{\vec n\cdot \vec {n_a}}{\Vert \vec n\Vert^2 }\\ \beta=\frac{\vec n\cdot \vec {n_b}}{\Vert \vec n\Vert^2 }\\ \gamma=\frac{\vec n\cdot \vec {n_c}}{\Vert \vec n\Vert^2 } $$

概率

随机变量、期望

方差:$V(X)=E((X-E(X))^2)=E(X^2)-E(X)^2$

期望与方差的运算

标准差

连续随机变量取任何特定值的概率为零

概率密度函数(Probability Density Function)

蒙特卡罗积分

使用随机数进行数值积分

$$ \int_Df(x)\mathrm{d}x=\overline{f(x)}\times\int_D 1\mathrm{d}x $$

所以一般是求平均值,然后乘上一个常数

重要性采样:当函数的高值和低值变化很大时,将样本集中在某些区域,然后用权值校正不均匀性。使用概率密度函数

具体流程为:

  1. 确定采样的函数与定义域
  2. 确定一个随机生成采样点的算法,同时确定采样点的概率密度函数
  3. 计算 ${f(x_i)}/{p(x_i)}$ 的均值

练习

  1. 浮点数的基数是无穷
  2. 可以实现 32 到 64,让它有明确的逆,但不是所有函数都可逆
  3. $C=\{(x,y,z)|x,y,z\in[0,1]\}$
  4. $\log_bx=\frac{\ln x}{\ln b}$,如果 $b$ 是负数,那么根据 IEEE,应该返回 NaN
  5. $x^3+3x+2=0$,$x=\frac{-3\pm\sqrt{3^2-4\times 2}}{2}=-1/-2$
  6. 代码如下:
if a == 0:
   if b == 0:
       return 0
   else:
       x1 = -c / b
       return 1, x1
else:
   delta = b * b - 4 * a * c
   if delta < 0:
       return 0
   elif delta == 0:
       x1 = -b / (2 * a)
       return 1, x1
   else:
       x1 = (-b + sqrt(delta)) / (2 * a)
       x2 = (-b + sqrt(delta)) / (2 * a)
       if x1 > x2:
           x1, x2 = x2, x1
       return 2, x1, x2
  1. $\vec u=\frac{\vec a}{\Vert\vec a\Vert}$,$\vec w=\frac{\vec u \times\vec b}{\Vert\vec u \times\vec b\Vert}$,$\vec v=\vec w \times\vec u$
  2. $(2x,1,9z)$
  3. $\begin{bmatrix}x\\y\end{bmatrix}=\begin{bmatrix}x_c+a\cos\phi\\y_c+b\sin\phi\end{bmatrix}$
  4. $x+y+z-1=0$(点法式推导),$\vec p(u,v)=(1,0,0)+u(-1,1,0)+v(-1,0,1)$(实际上是重心坐标系),$(1,1,1)$(叉乘即可)
  5. 分为以下几步(https://cloud.tencent.com/developer/article/2313839):
    • 计算四个叉乘:$d_1=\overrightarrow{a_0b_0}\times\overrightarrow{b_0a_1}$、$d_2=\overrightarrow{a_0b_1}\times\overrightarrow{b_1a_1}$、$d_3=\overrightarrow{b_0a_0}\times\overrightarrow{a_0b_1}$、$d_4=\overrightarrow{b_0a_1}\times\overrightarrow{a_1b_1}$
    • 如果 $d_1\cdot d_2<0$($b_0$ 与 $b_1$ 在 $\overrightarrow{a_0a_1}$ 两侧)且 $d_3\cdot d_4<0$($a_0$ 与 $a_1$ 在 $\overrightarrow{b_0b_1}$ 两侧),那么相交
    • 对于 $d_1$ 到 $d_4$,如果存在一个 $d_i=0$ 且对应的点在线段内部,那么相交
    • 上面的情况都不满足则不相交
  6. 前面说的笛卡尔坐标系转重心坐标系就行