最近在重温计算机图形学的基础知识,期望能做到温故知新,加深对其的理解,以便能从容应对工作中各种情况。
小弟水平有限,若有不正确之处,欢迎大家批评指正。
相关文章链接:
【计算机图形学基础】线性代数基础1
【计算机图形学基础】线性代数基础2
【计算机图形学基础】相机矩阵
【计算机图形学基础】投影矩阵
【计算机图形学基础】光照模型和着色频率
【计算机图形学基础】阴影映射
目录索引
1 线性表达
图形学中,简单的位置可以按如下表达:
p ( t ) ⃗ = p ⃗ + v t \vec{p(t)} = \vec{p}+ vt p(t)=p+vt;
其中v是速度,t是时间:
也可按两点间的插值表示:
p ( t ) ⃗ = p ⃗ + t ( q ⃗ − p ⃗ ) \vec{p(t)} = \vec{p}+ t(\vec{q} - \vec{p}) p(t)=p+t(q−p);经变换后,表达式可转换为如下:
p ( t ) ⃗ = ( 1 − t ) p ⃗ + t q ⃗ \vec{p(t)} = (1 - t)\vec{p} + t\vec{q} p(t)=(1−t)p+tq;
如下图所示:
2 矢量点积的应用
2.1 确定点和平面位置关系
如下所示,有平面
S
S
S 、其法向量
n
⃗
\vec{n}
n 和任意点
p
p
p。求取点和面之间的关系。
根据向量
p
c
⃗
\vec{pc}
pc 和 法向量
n
⃗
\vec{n}
n 的点乘,可以推断出
p
p
p 和面的关系:
得到的标量
s
s
s 是有符号的:
s
>
0
s > 0
s>0 表示点
p
p
p 在面的上方,同面法向量一侧;
s
=
=
0
s == 0
s==0 表示点
p
p
p 刚好在面上;
s
<
0
s < 0
s<0 表示点
p
p
p 在面的下方,与面法向量异侧。
2.2 点和球的碰撞检测
如下所示,点
p
p
p 以速度向量
v
v
v 进行运动,检测
p
p
p 是否和球体
c
c
c 碰撞。
如果有碰撞发生,则
p
(
t
)
p(t)
p(t) 和圆心
c
c
c 的距离刚好为半径
r
r
r。
∣ ∣ p ( t ) − c ∣ ∣ = r 2 ||p(t) - c|| = r^{2} ∣∣p(t)−c∣∣=r2, 可转换为点积:
( p − c + v t ) ⋅ ( p − c + v t ) = r 2 (p - c + vt) \cdot (p - c + vt) = r^2 (p−c+vt)⋅(p−c+vt)=r2
其中,只有 t t t 是未知数。
可用矢量相乘的分配律展开,有:
( v ⋅ v ) t 2 (v \cdot v)t^2 (v⋅v)t2 + 2 ( p − c ) ⋅ v t 2(p - c) \cdot vt 2(p−c)⋅vt + ( p − c ) ⋅ ( p − c ) (p-c) \cdot (p-c) (p−c)⋅(p−c) - r 2 r^2 r2 = 0。
因此,问题转换为解一元二次方程:
若
t
t
t 无解,则说明点和球没有碰撞;
若
t
t
t 有唯一解,则说明点沿着球的切线擦过;
若
t
t
t 有两个解,则需要求出
t
>
0
t > 0
t>0中的最小解,即点和球的碰撞时刻。
3 矢量叉乘的应用
3.1 求三角形的法向量和面积
有如下所示的三角形:
边
x
10
x_{10}
x10 =
x
1
−
x
0
x_{1} - x_{0}
x1−x0,边
x
20
x_{20}
x20 =
x
2
−
x
0
x_{2} - x_{0}
x2−x0;
因此法向量 n ⃗ \vec{n} n = x 10 × x 20 ∣ ∣ x 10 × x 20 ∣ ∣ \frac{x_{10} \times x_{20} }{|| x_{10} \times x_{20} ||} ∣∣x10×x20∣∣x10×x20。
三角形面积 = = = 底 × \times × 高 / / / 2。
因此有Area = ∣ ∣ x 10 ∣ ∣ ||x_{10}|| ∣∣x10∣∣ h h h / 2 /2 /2,其中将高 h h h 替换,有:
Area = ∣ ∣ x 10 ∣ ∣ ||x_{10}|| ∣∣x10∣∣ ∣ ∣ x 20 ∣ ∣ ||x_{20}|| ∣∣x20∣∣ s i n ( θ ) sin(\theta) sin(θ) / 2 /2 /2;
上述 ∣ ∣ x 10 ∣ ∣ ||x_{10}|| ∣∣x10∣∣ ∣ ∣ x 20 ∣ ∣ ||x_{20}|| ∣∣x20∣∣ s i n ( θ ) sin(\theta) sin(θ) 实际为叉乘后向量的大小值,那么面积公式中可以用叉乘的值来替换:
Area = ∣ ∣ x 10 × x 20 ∣ ∣ ||x_{10} \times x_{20}|| ∣∣x10×x20∣∣ / 2 /2 /2。
综上,矢量叉乘可用来计算三角形的法向量和面积。
3.2 求四面体的体积
四面体的体积 = 底面积 x 高 / 3。
四面体有三边,分别为 x 10 x_{10} x10 = x 1 − x 0 x_{1} - x_{0} x1−x0, x 20 x_{20} x20 = x 2 − x 0 x_{2} - x_{0} x2−x0 和 x 30 x_{30} x30 = x 3 − x 0 x_{3} - x_{0} x3−x0。
根据3.1小节的内容,底面积Area = ∣ ∣ x 10 × x 20 ∣ ∣ ||x_{10} \times x_{20}|| ∣∣x10×x20∣∣ / 2。
该底面对应的高实际为 x 30 x_{30} x30 在底面法线上的投影。
底面法线 n ⃗ \vec{n} n = x 10 × x 20 ∣ ∣ x 10 × x 20 ∣ ∣ \frac{x_{10} \times x_{20} }{|| x_{10} \times x_{20} ||} ∣∣x10×x20∣∣x10×x20。
因此 h h h = x 30 x_{30} x30 ⋅ \cdot ⋅ n ⃗ \vec{n} n = x 30 x_{30} x30 ⋅ \cdot ⋅ x 10 × x 20 ∣ ∣ x 10 × x 20 ∣ ∣ \frac{x_{10} \times x_{20} }{|| x_{10} \times x_{20} ||} ∣∣x10×x20∣∣x10×x20。
将上式子和底面积相结合,有:
Volume = ∣ ∣ x 10 × x 20 ∣ ∣ ||x_{10} \times x_{20}|| ∣∣x10×x20∣∣ x 30 x_{30} x30 ⋅ \cdot ⋅ x 10 × x 20 ∣ ∣ x 10 × x 20 ∣ ∣ \frac{x_{10} \times x_{20} }{|| x_{10} \times x_{20} ||} ∣∣x10×x20∣∣x10×x20 / 6。
综上,四面体的体积为: x 30 ⋅ ( x 10 × x 20 ) 6 \frac{x_{30}\cdot(x_{10}\times x_{20})}{6} 6x30⋅(x10×x20)。
注意,Volume也有正负;
若Volume > 0,则表示
x
3
x_{3}
x3 在底面的上方:
若Volume == 0,则表示
x
3
x_{3}
x3 就在底面中:
若Volume < 0,则表示
x
3
x_{3}
x3 在底面下方:
3.3 点和三角形的碰撞检测
若点
p
p
p 和 三角形发生了碰撞,那么点
p
p
p 和
△
x
0
x
1
x
2
\bigtriangleup x_{0}x_{1}x_{2}
△x0x1x2 所形成的四面体的体积为0。
根据3.2小节的内容,有:
( p ( t ) − x 0 ) ⋅ ( x 10 × x 20 ) (p(t) - x_{0}) \cdot(x_{10}\times x_{20}) (p(t)−x0)⋅(x10×x20) = 0 0 0;
( p − x 0 + t v ) ⋅ ( x 10 × x 20 ) (p - x_{0} + tv) \cdot(x_{10}\times x_{20}) (p−x0+tv)⋅(x10×x20) = 0 0 0,因此,将模型转换为解未知数t:
t t t = − ( p − x 0 ) ⋅ ( x 10 × x 20 ) v ⋅ ( x 10 × x 20 ) -\frac{(p - x_{0}) \cdot(x_{10}\times x_{20})}{v \cdot (x_{10}\times x_{20})} −v⋅(x10×x20)(p−x0)⋅(x10×x20)。
若 t t t有解,求解后,需要判断此时的 p p p 点是否在 △ x 0 x 1 x 2 \bigtriangleup x_{0}x_{1}x_{2} △x0x1x2 内部,若在在 △ x 0 x 1 x 2 \bigtriangleup x_{0}x_{1}x_{2} △x0x1x2 内部,则表明发生了碰撞检测。判断点是否在三角形内部,见线性代数基础1中的1.2.2-(3) 小节。
4 矩阵(补充)
4.1 正交矩阵
正交矩阵由正价的单位向量组成,如下所示:
正交矩阵中,向量自身点积为1,向量之间的点积为0。
因此,正交矩阵有下述性质:
因此,有
A
T
A^{T}
AT =
A
−
1
A^{-1}
A−1。
4.2 旋转被正交矩阵表示
A
A
A
⋅
\cdot
⋅
x
⃗
\vec{x}
x =
u
⃗
\vec{u}
u,其中
x
⃗
\vec{x}
x =
(
1
0
0
)
\begin{pmatrix}1\\0\\0\end{pmatrix}
⎝
⎛100⎠
⎞;
A A A ⋅ \cdot ⋅ y ⃗ \vec{y} y = v ⃗ \vec{v} v,其中 y ⃗ \vec{y} y = ( 0 1 0 ) \begin{pmatrix}0\\1\\0\end{pmatrix} ⎝ ⎛010⎠ ⎞;
A A A ⋅ \cdot ⋅ z ⃗ \vec{z} z = w ⃗ \vec{w} w,其中 z ⃗ \vec{z} z = ( 0 0 1 ) \begin{pmatrix}0\\0\\1\end{pmatrix} ⎝ ⎛001⎠ ⎞;
A A A ⋅ \cdot ⋅ [ x x x y y y z z z] = [ u u u v v v w w w] ,而 [ x x x y y y z z z] 实际为单位阵 I I I。
因此, A A A = [ u u u v v v w w w],而 u ⃗ \vec{u} u、 v ⃗ \vec{v} v、 w ⃗ \vec{w} w 是坐标轴,因此它们是正交的。
综上,旋转动作可以被正交阵表示。
4.3 奇异值分解(Singular Value Decomposition)
任意一个矩阵可以被分解为三个部分表示: A A A = U D V T UDV^{T} UDVT。
其中
D
D
D是对角阵,
U
U
U 和
V
V
V 是正交阵。对角阵是对角线上的元素
d
i
>
=
0
d_{i} >= 0
di>=0,其余元素均为0的矩阵。
上述分解的几何意义是:任何的线性变换,都可以分解为三个操作:旋转
V
T
V^{T}
VT、缩放
D
D
D 和旋转
U
U
U 。
① 通过
V
T
V^{T}
VT 将坐标系旋转到特定位置上;
② 在该位置上,通过对角阵
D
D
D 对坐标系进行缩放,使坐标系变为目标尺寸;
③ 将坐标系通过
U
U
U旋转到目标方向上。
5 参考
GAMES103_Lecture 02_Math Background: Vector, Matrix and Tensor Calculus