• 旋转轴 uR 的反对称部分 (R - R^T) 相关。

旋转向量也可以方便地进行插值。正确的方法是:计算从旋转A到旋转B的相对旋转,将其表示为轴角 (u, Δθ),然后对角度进行线性插值 θ_t = t * Δθ,再利用罗德里格斯公式构造中间旋转。注意:直接对两个旋转向量做线性插值通常得不到最短路径的平滑旋转。

四元数 (Quaternions) 🧮

四元数是表示旋转最强大、计算最高效的工具之一。它是一个四维超复数,通常写为:

q = [s, v] = s + xi + yj + zk,其中 s 是实部,v = (x, y, z) 是虚部(向量部分)。

用于表示旋转的必须是单位四元数,即满足 s^2 + x^2 + y^2 + z^2 = 1。单位四元数可以表示绕轴 u 旋转 θ 角:

公式: q = [cos(θ/2), sin(θ/2) * u]

一个三维向量 v 的旋转可以通过四元数乘法(“三明治”乘法)实现:

公式: v' = q * v * q^{-1}

其中 v 被提升为纯四元数 [0, v]q^{-1} = q*(共轭四元数,对于单位四元数)。

四元数的优势包括:

  • 高效组合:多个旋转连续作用,只需将对应的四元数相乘。

  • 平滑插值:可以在四维单位球面上进行球面线性插值 (Slerp),得到角速度恒定的最平滑旋转路径。其公式为:

    公式: Slerp(q0, q1, t) = (sin((1-t)Ω) / sinΩ) * q0 + (sin(tΩ) / sinΩ) * q1

    其中 Ωq0q1 之间的夹角。

  • 避免奇异性:没有万向锁问题。

需要注意的是,四元数 q-q 表示同一个旋转。在进行Slerp插值时,应确保选择最短弧,通常通过检查点积 q0·q1,若为负则将一个四元数取反。

角速度与旋转的微分关系 ⏱️

在物理模拟中,我们经常需要处理旋转随时间变化的情况,这就涉及到角速度 ω

旋转矩阵 R 对时间的导数与角速度 ω(在世界坐标系下)满足以下关系:

公式: dR/dt = [ω]× * R

其中 [ω]× 是角速度向量 ω 对应的叉乘矩阵(反对称矩阵)。

这个公式的物理意义是:刚体上一点的世界坐标速度 v = ω × (R * p_local)

如果角速度 ω' 是定义在局部坐标系下的,则关系变为:

公式: dR/dt = R * [ω']×

类似地,对于四元数 q,其微分方程为:

公式: dq/dt = (1/2) * ω * q (世界坐标系角速度)

dq/dt = (1/2) * q * ω' (局部坐标系角速度)

这里的乘法是四元数乘法,ω 需写为纯四元数 [0, ω]

这些方程是进行刚体动力学数值积分的基础。

神经网络中的旋转表示 🤖

当使用神经网络处理旋转(如姿态估计、动作生成)时,传统的表示方法可能面临挑战:

  • 奇异性:欧拉角有万向锁。

  • 周期性/多值性:轴角中,(θ, u)(2π-θ, -u) 表示相同旋转;四元数中 q-q 相同。这会导致损失函数存在多个极小值,不利于优化。

  • 约束:旋转矩阵需要正交约束,四元数需要单位约束。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/88e61ffa86f5b02f5dec97a407b62f08_12.png

一种在实践中表现良好的表示是 6D 连续旋转表示。网络输出一个6维向量 [a, b],然后通过以下过程得到一个有效的旋转矩阵:

  1. 将前3维 a 归一化得到第一个基向量 b1

  2. 将后3维 b 减去其在 b1 上的投影,然后归一化,得到与 b1 正交的第二个基向量 b2

  3. 通过叉乘 b3 = b1 × b2 得到第三个正交基向量。

  4. 组合 [b1, b2, b3] 即得到一个合法的旋转矩阵 R ∈ SO(3)

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/88e61ffa86f5b02f5dec97a407b62f08_14.png

这种方法避免了显式的周期性,提供了连续的映射,更易于神经网络学习和优化。

总结

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/88e61ffa86f5b02f5dec97a407b62f08_16.png

本节课中我们一起深入探讨了图形学中的旋转变换。我们从旋转作为特殊正交群 SO(3) 的基本定义出发,理解了其三维流形的本质。然后,我们系统地学习了三种核心的旋转表示法:

  1. 欧拉角:直观但存在万向锁,适合用户交互。

  2. 轴角/旋转向量:直接体现旋转几何,是推导的基础。

  3. 四元数:无奇异性、计算高效、插值平滑,是存储和计算旋转的优选。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/88e61ffa86f5b02f5dec97a407b62f08_18.png

我们还探讨了旋转的微分与角速度的关系,这是物理模拟的基石。最后,我们了解了在为神经网络设计旋转输出时,6D连续表示等现代方法的优势。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/88e61ffa86f5b02f5dec97a407b62f08_20.png

掌握这些表示方法及其相互转换,是进行三维图形编程、机器人学、动画和物理模拟的必备技能。希望本教程能帮助你建立起清晰的概念框架。

GAMES001-图形学中的数学—P5-主成分分析与奇异值分解—GAMES-Webinar—BV1MF4m1V7e3_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/bb977eb198a22aec81d6d71d60cb6fd1_0.png

在本节课中,我们将要学习线性代数中两个极其重要的概念:奇异值分解与主成分分析。它们在图形学、数据科学和机器学习等领域有着广泛的应用。我们将从实对称矩阵的性质出发,推导出奇异值分解,并探讨其在求解矩阵方程、理解几何变换等方面的应用。随后,我们将介绍主成分分析这一降维技术,并了解其在点云处理、数据压缩等图形学任务中的应用。

实对称矩阵的性质 🔍

上一节我们介绍了矩阵的基本概念。本节中,我们来看看一类特殊的矩阵——实对称矩阵,并证明其两个关键性质,为后续推导奇异值分解奠定基础。

定理一:实对称矩阵的特征值是实数。

对于任意一个实对称矩阵 S,存在特征值 λ 和对应的特征向量 x,满足 Sx = λx。我们假设 x 已归一化,即 xx = 1。对等式两边取共轭,得到 Sxᴴ = λ* xᴴ。由于 S 是实对称矩阵,其共轭等于自身。在等式左边乘以 xᵀ,得到 xSxᴴ = xᵀλ* xᴴ = λ*。另一方面,对原式 Sx = λx 两边转置,得到 xS = λxᵀ。在此式右边乘以 xᴴ,得到 xSxᴴ = λxxᴴ = λ。比较两个结果,得到 λ = λ*,因此 λ 是实数。

定理二:实对称矩阵不同特征值的特征向量相互正交。

取两个不同的特征值 λ₀, λ₁ 及其对应的特征向量 x₀, x₁。从等式 x₀S = λ₀x₀ᵀ 出发,右边乘以 x₁,得到 x₀Sx₁ = λ₀x₀x₁。由于 Sx₁ = λ₁x₁,代入得 x₀ᵀλ₁x₁ = λ₁x₀x₁。因此有 λ₀x₀x₁ = λ₁x₀x₁。由于 λ₀ ≠ λ₁,要使得等式成立,必须有 x₀x₁ = 0,即 x₀x₁ 正交。

基于以上性质,任意实对称矩阵 S 可以进行特征值分解:

S = QΛQ

其中,Q 是由特征向量组成的正交矩阵(满足 QQ = I),Λ 是由特征值构成的对角矩阵。

如果 S 是半正定矩阵(即所有特征值 λᵢ ≥ 0),我们可以定义其平方根矩阵 P

P = Q√Λ Q

使得 P² = S。此外,实对称矩阵的迹等于其所有特征值之和:tr(S) = Σ λᵢ

奇异值分解的推导 🧬

理解了实对称矩阵后,本节中我们来看看如何将其性质推广到任意矩阵,从而得到奇异值分解。

考虑一个任意的 m × n 矩阵 A,其秩为 r。构造矩阵 S = AAS 是一个 n × n 的实对称半正定矩阵。根据上一节的结论,S 可以进行特征值分解,找到 r 个相互正交的特征向量 vᵢ 和对应的特征值 λᵢ (λᵢ ≥ 0)。

我们有以下关系:

AA vᵢ = λᵢ vᵢ

接下来,我们定义一组新的向量 uᵢ

uᵢ = (1 / √λᵢ) A vᵢ (对于 λᵢ > 0)

可以证明,这样定义的 uᵢ 也是一组正交基。然后,我们通过施密特正交化,将 vᵢ 扩充为 Rⁿ 空间的一组标准正交基,将 uᵢ 扩充为 Rᵐ 空间的一组标准正交基。对于扩充的向量(对应 λᵢ = 0),有 A vᵢ = 0

将所有这些关系用矩阵形式表示。令 V 的每一列为 vᵢU 的每一列为 uᵢΣ 是一个 m × n 的“对角”矩阵,其前 r 个对角元 σᵢ = √λᵢ,其余元素为 0。则上述关系可以写为:

A V = U Σ

由于 V 是正交矩阵,Vᵀ = V⁻¹。在等式两边右乘 Vᵀ,我们得到奇异值分解的最终形式:

A = U Σ V

其中:

  • U 是 m × m 的正交矩阵。

  • Σ 是 m × n 的矩阵,其对角元 σᵢ 称为 A奇异值,数量等于矩阵的秩 r。

  • V 是 n × n 的正交矩阵。

奇异值分解的应用:矩阵的逆与方程求解 ⚙️

上一节我们得到了奇异值分解的形式。本节中我们来看看它在解决线性代数核心问题——求逆和解方程——中的应用。

1. 矩阵的逆

对于一个可逆的方阵 A,其奇异值分解为 A = UΣVᵀ。那么它的逆矩阵可以方便地求出:

A⁻¹ = (UΣVᵀ)⁻¹ = V Σ⁻¹ U

其中 Σ⁻¹ 是将 Σ 的非零对角元取倒数得到的对角矩阵。

2. 矩阵的伪逆与方程求解

对于非方阵或不满秩的矩阵 A,严格意义上的逆不存在。但我们可以在最小二乘意义下定义伪逆 A⁺,用于求解方程 Axb

以下是求解不同类型方程时伪逆的形式:

  • 超定方程(方程数 > 未知数):通常无精确解,转而求最小化残差 ||Ax - b||² 的解。该解为 x = Ab,其中 A⁺ = (AA)⁻¹Aᵀ,称为左逆。利用SVD,A⁺ = V ΣUᵀ。

  • 欠定方程(方程数 < 未知数):有无穷多解,转而求满足 Ax = b 且范数 ||x|| 最小的解。该解为 x = Ab,其中 A⁺ = Aᵀ(A Aᵀ)⁻¹,称为右逆。利用SVD,同样有 A⁺ = V ΣUᵀ。

在SVD框架下,Σ⁺ 是一个 n × m 的矩阵,它是 Σ 的“转置”,并将其非零奇异值替换为相应的倒数。伪逆 A⁺ = V ΣUᵀ 是一个统一的表达式,涵盖了左逆、右逆以及可逆方阵的逆。

奇异值分解在图形学中的应用实例 🎨

理解了奇异值分解的数学原理后,本节中我们来看看它在图形学中的两个具体应用:理解线性变换和形状匹配。

1. 理解线性变换

任意一个线性变换 x’ = A xA 为3×3矩阵)都可以进行SVD分解:A = UΣVᵀ。这个分解可以理解为三个连续的变换:

  1. Vx:旋转(因为 V 是正交矩阵)。

  2. Σ (Vx):沿坐标轴的缩放(拉伸或压缩)。

  3. U (Σ Vx):再次旋转。

因此,任何线性变换本质上都可以分解为“旋转-缩放-旋转”的组合。这被称为极分解的另一种形式:A = RS,其中 R = UVᵀ 是旋转矩阵,S = VΣVᵀ 是一个对称正定矩阵,代表拉伸。

2. 形状匹配算法

形状匹配的目标是:给定一组点从位置 qᵢ 变形到 pᵢ,找到一个最优的刚性变换(旋转 R 和平移 t),使得变换后的 qᵢ 尽可能接近 pᵢ。即最小化目标函数:

Σᵢ ||(R qᵢ + t) - pᵢ||²

求解步骤如下:

  1. 计算两组点的质心:q_c = (1/N) Σ qᵢ, p_c = (1/N) Σ pᵢ

  2. 计算去质心坐标:q̃ᵢ = qᵢ - q_c, p̃ᵢ = pᵢ - p_c

  3. 构造矩阵 H = Σᵢ p̃ᵢ q̃ᵢᵀ。

  4. H 进行奇异值分解:H = UΣVᵀ。

  5. 最优旋转矩阵 R = V Uᵀ(需检查行列式,若为-1则需调整)。

  6. 最优平移向量 t = p_c - R q_c

该算法在图形学的碰撞处理、模型对齐等领域有广泛应用。

主成分分析:数据降维技术 📉

上一节我们看到了SVD在几何上的应用。本节中我们来看看另一个紧密相关的技术——主成分分析,它主要用于数据降维和特征提取。

PCA的目标是:对于一个高维数据集,找到一个低维子空间,使得数据在该子空间上的投影能最大程度保留原始数据的方差(即信息)。

算法推导:

假设我们有 N 个 d 维数据点 x₀, x₁, …, x_{N-1}

  1. 计算数据集的均值:μ = (1/N) Σ xᵢ

  2. 计算协方差矩阵:S = (1/N) Σ (xᵢ - μ)(xᵢ - μ)ᵀ。

  3. 对协方差矩阵 S 进行特征值分解:S = QΛQᵀ。特征值 λᵢ 从大到小排列,对应的特征向量 qᵢ 称为主成分。

  4. 选择前 k 个最大的特征值对应的特征向量 q₀, q₁, …, q_{k-1},构成投影矩阵 P

  5. 任何数据点 x 的 k 维降维表示为:y = Pᵀ(x - μ)。

为什么最大特征值对应的特征向量是最佳投影方向?

最大化投影后数据的方差,等价于最大化 vS v,其中 v 是投影方向(单位向量)。而 vS v 的最大值就是 S 的最大特征值,在 v 为对应特征向量时取到。

主成分分析的应用与局限 🖼️

掌握了PCA的基本原理后,本节中我们来看看它在图形学中的典型应用,并认识其局限性。

应用实例:

  1. 点云法向估计:对于点云中一个点,取其邻域内的点构成一个局部数据集。对该数据集进行PCA,最小的特征值对应的特征向量方向近似为该点的法向方向。前两个特征向量则张成切平面。

  2. 数据压缩:例如,一张 512×512 的图片可以看作一个 262144 维的数据点。对多张人脸图片(数据集)进行PCA,可以得到一个低维的“特征脸”空间。任何一张新人脸都可以用少数几个主成分的系数来近似表示,从而实现压缩。

  3. 模型降阶:在物理模拟中,系统的自由度可能极高。可以预先运行多次模拟,将结果作为高维数据点,然后用PCA提取主要变化模式。后续模拟只需在低维的主成分空间中进行,大幅提升计算效率。

局限性:

PCA是一种线性降维方法。它假设数据的主要结构存在于一个线性子空间中。对于具有非线性结构的数据(例如一个三维空间中的螺旋线或圆圈),PCA无法有效降维。此时,需要借助非线性降维方法,如:

  • 核PCA:先将数据通过非线性函数映射到高维空间,再在高维空间中进行线性PCA。

  • 自编码器:使用神经网络学习数据从高维到低维(编码)以及从低维恢复至高维(解码)的非线性映射,其隐空间表示即为降维结果。

总结 📚

本节课中我们一起学习了图形学数学基础中的两个核心工具:奇异值分解与主成分分析。

我们首先从实对称矩阵的性质出发,严谨地推导出了任意矩阵的奇异值分解形式 A = UΣVᵀ。我们探讨了SVD在求解矩阵逆、伪逆以及线性方程组(超定、欠定)中的应用。在图形学中,SVD帮助我们理解线性变换的几何本质(旋转与缩放),并构成了形状匹配等算法的数学基础。

随后,我们介绍了主成分分析这一数据降维技术。PCA通过计算数据协方差矩阵的特征向量,找到数据方差最大的投影方向,从而实现高效的数据压缩和特征提取。我们看到了PCA在点云处理、图像压缩和模拟加速中的应用,同时也指出了其作为线性方法的局限性。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/bb977eb198a22aec81d6d71d60cb6fd1_2.png

这些概念是连接线性代数与图形学应用的重要桥梁,理解它们将为学习更高级的图形学主题奠定坚实的基础。

GAMES001-图形学中的数学—P6-插值-拟合—GAMES-Webinar—BV1MF4m1V7e3_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/72df9b1d8c5233ee758623a4d11f9a23_0.png

在本节课中,我们将学习图形学中两个核心的数学概念:插值拟合。我们将从定义和区别入手,逐步介绍多种插值方法,并探讨如何通过拟合来逼近带有噪声的数据。课程内容力求简单直白,确保初学者能够理解。

概述

插值与拟合是处理离散数据、构建连续函数或曲面的基础技术。它们的核心区别在于:

  • 插值:要求构造的函数必须经过所有给定的数据点。

  • 拟合:构造的函数无需经过所有数据点,旨在捕捉数据的整体趋势,常用于处理带有噪声的数据。

接下来,我们将首先深入探讨各种插值技术。

插值方法

线性插值 📏

线性插值是最简单的插值方法。给定两个点 (x0, y0)(x1, y1),我们假设它们之间的函数关系是一条直线。

其函数表达式为:

y = (1 - t) * y0 + t * y1

其中,t = (x - x0) / (x1 - x0),表示点 x 在线段 [x0, x1] 中的比例。

当有多个点时,只需在每两个相邻点之间进行线性插值,然后将所有线段连接起来。这种方法得到的曲线是连续的,但在连接点处的导数不连续,我们称这种连续性为 C0连续

上一节我们介绍了最简单的线性插值,本节中我们来看看如何通过更高阶的多项式来获得更光滑的曲线。

多项式插值(拉格朗日插值)🔢

为了获得更光滑的曲线(例如导数连续),我们可以使用多项式插值。其核心思想是:给定 n+1 个数据点,可以唯一确定一个 n 阶多项式,使其经过所有点。

拉格朗日插值给出了这个多项式的显式表达式:

P(x) = Σ [ y_j * L_j(x) ], 对 j0n 求和。

其中,L_j(x) 称为拉格朗日基函数,其定义为:

L_j(x) = Π [ (x - x_i) / (x_j - x_i) ], 对 i0ni ≠ j 求积。

拉格朗日基函数具有关键性质:L_j(x_k) = δ_jk(当 j=k 时为1,否则为0)。这保证了插值多项式必然经过所有数据点。

一个 n 阶多项式具有 C^(n-1) 连续性,因此曲线非常光滑。然而,高阶多项式插值存在龙格现象:当数据点等距分布且多项式阶数较高时,插值结果在区间边缘会产生剧烈的震荡,与真实函数偏离甚远。

由于龙格现象的存在,直接使用高阶全局多项式插值并不总是可靠。接下来,我们将介绍一种能避免此问题的方法。

样条插值 🧩

样条插值通过拼接多段低阶多项式来构造整体曲线,从而避免高阶震荡。每一段的多项式阶数较低,因此不会剧烈震荡。

以下是两种常见的样条插值:

二阶样条插值

  • 每一段曲线都是一个二次函数。

  • 需要满足条件:1) 经过区间两端点(插值条件);2) 在内部连接点处一阶导数连续。

  • 这需要求解一个线性方程组。该方法得到的曲线是 C1连续 的,但改变一个数据点会影响整个曲线(缺乏局部性)。

三阶样条插值

  • 每一段曲线都是一个三次函数。

  • 需要满足条件:1) 经过区间两端点;2) 在内部连接点处一、二阶导数均连续。

  • 同样需要求解线性方程组。该方法得到的曲线是 C2连续 的,非常光滑,但也缺乏局部性。

样条插值虽然光滑,但需要解方程且缺乏局部性。下面我们介绍一种兼具局部性和无需解方程的方法。

三阶厄米特插值 🔗

三阶厄米特插值在每一段上也是三次函数,但它通过直接指定区间端点的函数值导数值来确定该段曲线。

对于区间 [x0, x1],给定端点函数值 y0, y1 和导数值 m0, m1,可以唯一确定一个三次多项式。其解可以写成基函数的形式:

y = y0 * H00(t) + m0 * H10(t) + y1 * H01(t) + m1 * H11(t)

其中 t = (x - x0)/(x1 - x0)H00, H10, H01, H11 是定义在 [0, 1] 上的三次多项式,称为厄米特基函数

通过规定每个数据点上的导数值(例如,取左右邻接线段斜率的平均值),并将多段厄米特曲线拼接,就能得到一条整体的 C1连续 插值曲线。这种方法无需解大型方程组,且具有局部性:修改一个数据点,只影响其相邻的曲线段。

我们已经介绍了几种主要的插值方法,现在用一个统一的视角——基函数来理解它们。

基函数视角 🧠

大多数插值方法都可以写成统一形式:

f(x) = Σ [ y_i * φ_i(x) ]

其中 φ_i(x) 就是与第 i 个数据点对应的基函数

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/72df9b1d8c5233ee758623a4d11f9a23_2.png

基函数的核心性质是:φ_i(x_j) = δ_ij。这保证了插值条件自动满足。

不同的插值方法,对应不同的基函数:

  • 线性插值:基函数是分段的线性“帽状”函数。

  • 拉格朗日插值:基函数是全局的高阶多项式。

  • 三阶样条插值:基函数是通过解方程得到的分段三次函数,支撑范围较广。

  • 三阶厄米特插值:基函数是局部的分段三次函数,具有紧支撑性(只在局部非零),这是其局部性的体现。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/72df9b1d8c5233ee758623a4d11f9a23_4.png

多维与曲线插值

之前的讨论集中在一维函数插值。在图形学中,我们经常需要处理更高维度的插值问题。

曲线插值 🧵

问题:给定空间中一系列有序的点 P0, P1, ..., Pn,求一条经过所有这些点的光滑曲线。

解法:将三阶厄米特插值推广到向量形式。将标量函数值 y 和导数值 m 替换为位置向量 P 和切线向量 T。插值公式变为:

C(t) = P0 * H00(t) + T0 * H10(t) + P1 * H01(t) + T1 * H11(t)

这样得到的是一条参数曲线,在图形学软件(如PPT的曲线工具)中广泛应用。

三角形插值(重心坐标)🔺

对于三角形内的点,可以使用重心坐标进行插值。三角形内任意点 P 可表示为三个顶点 A, B, C 的加权和:

P = α * A + β * B + γ * C

其中 (α, β, γ) 称为重心坐标,且 α + β + γ = 1α 等于 P 点对面小三角形面积与总面积之比。

重心坐标 α, β, γ 本身可以看作定义在三角形上的基函数,它们满足 φ_A(A)=1, φ_A(B)=φ_A(C)=0 等性质。这自然适用于在三角形顶点属性(如颜色、法线)之间进行插值。

像素插值(双线性与双三次)🖼️

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/72df9b1d8c5233ee758623a4d11f9a23_6.png

在图像处理中,常需要对像素网格进行插值,例如纹理映射中的放大。

  • 双线性插值:在 xy 两个方向上分别进行线性插值。

  • 双三次插值:在 xy 两个方向上分别进行三阶厄米特(或样条)插值,通常能获得更平滑、质量更高的结果。

点云插值(径向基函数)☁️

问题:给定空间中一组散乱的点 {xi} 及其函数值 {fi},求整个空间域的插值函数。

解法:使用径向基函数方法。假设插值函数形式为:

f(x) = Σ [ w_i * φ( ||x - x_i|| ) ], 对 i1n 求和。

其中 φ(r) 是径向基函数(如高斯函数、薄板样条),只与距离 r 有关。权重 {w_i} 通过求解线性方程组(强制满足所有点的插值条件)得到。

注意:在有些场景(如SPH流体、NeRF)中,类似的形式 f(x) = Σ [ f_i * φ( ||x - x_i|| ) ] 也被称为“插值”,但它并不经过数据点,而是将点上的值“涂抹”到周围空间,更接近一种平滑重建。

拟合方法

现在,我们转向不要求经过所有数据点的拟合技术。

最小二乘法拟合 📉

最小二乘法是最常用的拟合方法。它假设数据符合一个带有未知参数的模型(如 y = a*x + b),然后通过最小化所有数据点的预测值与真实值之差的平方和,来求解最优参数。

用矩阵表示:假设模型为 y = G * a,其中 G 是由基函数在数据点处取值构成的矩阵,a 是待求参数向量。给定数据向量 y,最优参数 a 的解为:

a = (G^T * G)^(-1) * G^T * y

这对应于求解一个超定方程组的最小二乘解。

最小二乘法假设全局数据符合同一个模型。接下来看一种更灵活的局部拟合方法。

移动最小二乘法 🏃

移动最小二乘法是一种局部拟合技术。对于每一个待求点 x,只使用其邻近的数据点进行拟合,且邻近点的权重随距离增加而衰减。

具体步骤:

  1. 对于待求点 x,选取其邻域内的一组数据点 {xi}

  2. x 的局部坐标系下,用一个低阶多项式(如一次或二次)f(r) = p^T * a 来拟合数据,其中 r = xi - x

  3. 最小化加权平方和:min Σ [ w_i * (f(r_i) - f_i)^2 ]

  4. 求解得到局部参数 a。此时,x 点本身的拟合值就是 a 的第一个分量,梯度信息也包含在 a 中。

这种方法无需全局模型假设,对每个点独立进行拟合,非常灵活,常用于点云数据处理和曲面重建。

随机抽样一致算法 🎲

RANSAC 用于处理包含大量异常值的数据拟合。其基本思想是:通过随机抽样和迭代,寻找一个被最多“内点”(符合模型的数据)支持的模型。

算法流程:

  1. 随机从数据集中选取拟合所需的最少样本数(如拟合直线选2个点)。

  2. 用这些样本计算一个模型。

  3. 统计整个数据集中有多少数据点与该模型的误差小于阈值(这些点称为“内点”)。

  4. 如果内点数量超过预设阈值,则认为模型较好;否则,回到步骤1。

  5. 重复多次,选择内点最多的那个模型,并用所有内点重新拟合最终模型。

RANSAC 能有效抵抗异常值的干扰,在图像匹配、点云配准等领域应用广泛。

总结

本节课中我们一起学习了图形学中的插值与拟合。

  • 插值强调经过数据点,我们介绍了从简单的线性插值,到光滑但可能震荡的多项式插值,再到稳定实用的样条插值和三阶厄米特插值,并扩展到曲线、三角形、像素和点云等不同场景。

  • 拟合不强求经过数据点,旨在捕捉趋势。我们学习了经典的最小二乘法,灵活的移动最小二乘法,以及抗噪声能力强的RANSAC算法。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/72df9b1d8c5233ee758623a4d11f9a23_8.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/72df9b1d8c5233ee758623a4d11f9a23_10.png

理解这些方法的原理、优缺点及适用场景,对于解决图形学中的几何建模、图像处理、数据重建等问题至关重要。

GAMES001-图形学中的数学—P7-傅里叶变换与球谐函数—GAMES-Webinar—BV1MF4m1V7e3_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_1.png

在本节课中,我们将学习图形学中两个核心的数学工具:傅里叶变换与球谐函数。我们将从基础概念出发,理解它们如何描述和分析函数,并探讨它们在图形学中的广泛应用。

傅里叶展开:从周期函数到三角级数 📈

上一节我们介绍了课程的整体安排,本节中我们来看看傅里叶展开。傅里叶展开描述了一个周期函数如何分解为一系列正弦和余弦函数的叠加。

例如,一个周期为 T 的方波信号,在 0T/2 时取值为 1,在 T/2T 时取值为 -1。这个函数可以展开为不同频率正弦和余弦函数的加权和。

写成公式如下:

f(t) = a_0/2 + Σ_{n=1}^{∞} [a_n cos(nωt) + b_n sin(nωt)]

其中,ω = 2π/T 是基频。系数 a_nb_n 可以通过积分公式求得:

a_n = (2/T) ∫_{0}^{T} f(t) cos(nωt) dt
b_n = (2/T) ∫_{0}^{T} f(t) sin(nωt) dt

这个过程就是将复杂的周期信号,分解为一系列简单谐波(正弦波)的过程。随着叠加的谐波数量增加,合成的波形会越来越接近原始方波。

傅里叶变换:从周期到非周期 🔄

上一节我们介绍了周期函数的傅里叶展开,本节中我们来看看如何将其推广到非周期函数。核心思想是将非周期函数视为周期无穷大的周期函数。

当周期 T 趋向于无穷大时,离散的频率求和就变成了连续的频率积分。由此我们得到傅里叶变换对:

正变换(从时域到频域):

F(ω) = ∫_{-∞}^{∞} f(t) e^{-iωt} dt

逆变换(从频域到时域):

f(t) = (1/2π) ∫_{-∞}^{∞} F(ω) e^{iωt} dω

这里,e^{iωt} = cos(ωt) + i sin(ωt) 是欧拉公式。F(ω) 是一个复函数,其模长表示频率 ω 成分的振幅,辐角表示相位。

本质上,傅里叶变换是在函数构成的线性空间中,做了一次基底的变换。原来我们默认使用狄拉克δ函数作为基,函数值 f(t) 就是其系数。傅里叶变换则换用复指数函数 e^{iωt} 作为新基,F(ω) 就是函数在这个新基下的展开系数。

离散傅里叶变换与快速算法 ⚡

上一节我们讨论了连续的傅里叶变换,但在计算机中,我们处理的是离散信号。离散傅里叶变换(DFT)是连续傅里叶变换的离散化形式。

对于一个长度为 N 的离散序列 x[n],其DFT X[k] 定义为:

X[k] = Σ_{n=0}^{N-1} x[n] e^{-i 2π k n / N}, k = 0, 1, ..., N-1

逆变换为:

x[n] = (1/N) Σ_{k=0}^{N-1} X[k] e^{i 2π k n / N}, n = 0, 1, ..., N-1

直接计算DFT的复杂度是 O(N^2)。快速傅里叶变换(FFT)算法利用分治思想,将复杂度降低到 O(N log N),使其得以广泛应用。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_3.png

以下是FFT在图形学中的一个经典应用:图像处理。

  • 图像压缩:对图像进行二维DFT得到频谱,保留低频分量(中心部分),丢弃高频分量,再进行逆变换,可以实现有损压缩(如JPEG格式)。

  • 边缘提取:对图像频谱进行高通滤波(保留外围高频,去除中心低频),再进行逆变换,可以得到图像的边缘信息。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_5.png

卷积定理:连接时域与频域的桥梁 🌉

上一节我们介绍了离散傅里叶变换,本节中我们来看看一个与之紧密相关的操作:卷积。卷积在信号处理和图像处理中无处不在,例如图像模糊、边缘检测等。

两个一维函数 f(t)g(t) 的卷积定义为:

(f * g)(t) = ∫_{-∞}^{∞} f(τ) g(t - τ) dτ

直观上,卷积是将函数 g 翻转并平移,然后与函数 f 逐点相乘并积分。

卷积定理揭示了卷积与傅里叶变换之间的美妙关系:

F{f * g} = F{f} · F{g}
F{f · g} = F{f} * F{g}

其中,F{·} 表示傅里叶变换,* 表示卷积,· 表示点乘。时域中的卷积,等价于频域中的乘法;时域中的乘法,等价于频域中的卷积。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_7.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_9.png

这个定理为分析许多问题提供了强大工具。例如,在图像处理中,用一个平均核对图像进行卷积(模糊操作),在频域看来,就是图像的频谱乘以该卷积核的频谱(一个低通滤波器),从而衰减高频信息。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_11.png

采样与走样:频域视角的分析 📊

上一节我们利用卷积定理分析了图像处理,本节中我们用它来分析图形学的另一个核心问题:采样与走样。

采样过程可以建模为原始连续信号 f(t) 与一个狄拉克梳状函数 Ш_T(t) 相乘:

f_s(t) = f(t) · Ш_T(t)

狄拉克梳状函数由一系列间隔为 T 的狄拉克δ函数组成,它只在采样点处有值。

根据卷积定理,时域的乘法对应频域的卷积。已知狄拉克梳状函数的傅里叶变换仍是狄拉克梳状函数,其间隔变为 2π/T。因此,采样后信号的频谱 F_s(ω) 是原始信号频谱 F(ω) 的周期性复制:

F_s(ω) = (1/T) Σ_{n=-∞}^{∞} F(ω - n * (2π/T))

采样定理(奈奎斯特定理) 指出:为了避免频谱复制时发生混叠(Aliasing),采样频率 1/T 必须至少是信号最高频率的两倍。如果采样频率过低,复制出的频谱就会重叠,导致无法从采样信号中无损恢复原始信号,这就是“走样”。

在图形学中,这解释了为什么对图像或场景进行欠采样(如光栅化时分辨率不足)会产生锯齿。反走样技术(如超采样、多重采样)的核心就是提高有效采样频率或预先过滤掉高于奈奎斯特频率的信号成分。

球谐函数:球面上的“傅里叶展开” 🌐

上一节我们在平直空间(时域/频域)讨论了傅里叶分析,本节中我们将其思想推广到球面坐标系。球谐函数(Spherical Harmonics, SH)就是定义在球面上的一组正交基函数。

在图形学中,许多函数定义在球面上,例如环境光照贴图、双向反射分布函数(BRDF)等。球谐函数提供了一种压缩和近似这些球面函数的有力工具。

球谐函数 Y_l^m(θ, φ) 的数学表达式较为复杂,包含连带勒让德多项式 P_l^m 和复指数项 e^{imφ}

Y_l^m(θ, φ) = N_l^m · P_l^m(cosθ) · e^{imφ}

其中,l 是阶数(l ≥ 0),m 是次数(-l ≤ m ≤ l)。N_l^m 是归一化常数。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_13.png

我们可以将球谐函数可视化:从球心出发,沿方向 (θ, φ) 的射线长度正比于 Y_l^m(θ, φ) 的值。随着阶数 l 增加,球面上的“波段”数量增多,表示更高的频率成分。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_15.png

任意一个球面函数 f(θ, φ) 可以投影到球谐基上,展开为:

f(θ, φ) = Σ_{l=0}^{∞} Σ_{m=-l}^{l} c_l^m Y_l^m(θ, φ)

系数 c_l^m 由内积求得:

c_l^m = ∫_{S^2} f(θ, φ) Y_l^m(θ, φ) dΩ

与傅里叶级数类似,我们可以用低阶(如前3阶或5阶)的球谐函数来近似原始球面函数,实现数据的有效压缩和降噪。这在实时渲染中用于近似环境光照和漫反射全局光照(Precomputed Radiance Transfer, PRT)等技术中至关重要。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_17.png

总结 📝

本节课中我们一起学习了图形学中两个强大的数学工具:

  1. 傅里叶变换:本质是函数空间的基变换,从时域基(δ函数)切换到频域基(复指数函数)。它让我们能从频率视角分析信号。

  2. 卷积定理:建立了时域卷积与频域乘法的等价关系,是分析采样、滤波等操作的核心。

  3. 采样与走样:从频域看,采样是频谱的周期性复制;欠采样会导致频谱混叠,产生走样。

  4. 球谐函数:可以看作是球坐标系下的“傅里叶展开”,为处理和压缩球面函数(如光照)提供了标准正交基。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/93f8fb7b4ed12f39bfd2768880f1cadb_19.png

理解这些概念,将为深入学习图形学中的渲染、采样、信号处理等高级主题打下坚实的基础。

GAMES001-图形学中的数学—P8-概率论-一----GAMES-Webinar—BV1MF4m1V7e3_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/d33b8ccc3d5f0c753a8f253fc090c6b4_0.png

在本节课中,我们将回顾概率论的基础知识。概率论是图形学中许多算法的基础,理解其核心概念至关重要。我们将从概率的定义出发,逐步介绍古典概型、条件概率、贝叶斯公式、随机变量及其分布、数字特征(期望与方差),最后简要介绍大数定律与中心极限定理。


什么是概率?🎲

概率的概念源于频率。对于一个随机试验(例如抛硬币),在相同条件下重复进行N次,事件A(例如正面朝上)发生了NA次。比值NA/N称为事件A发生的频率,记作fN(A)。频率是一个介于0和1之间的实数。

对于一个随机试验E,其样本空间S是所有可能结果的集合。对于E的每一个事件A,我们赋予一个实数P(A),称为事件A的概率。一个有效的概率定义必须满足以下三条公理:

  1. 非负性:对于任何事件A,有 P(A) ≥ 0。

  2. 规范性:必然事件的概率为1,即 P(S) = 1。

  3. 可列可加性:如果一系列事件A1, A2, … 两两互斥(不可能同时发生),则它们至少有一个发生的概率等于各自概率之和,即 P(∪Ai) = ΣP(Ai)。

当试验次数N趋向于无穷大时,事件A的频率fN(A)会趋向于其概率P(A)。此时,我们定义的P(A)才具有我们所理解的“可能性”的含义。


古典概型(等可能概型)⚖️

古典概型是一种简单且常见的概率模型。它满足两个条件:

  1. 试验的样本空间只包含有限个基本事件。

  2. 试验中每个基本事件发生的可能性相同。

在古典概型中,事件A的概率计算公式为:

P(A) = A包含的基本事件数 / 基本事件的总数

以下是几个古典概型的例子:

  • 抛硬币:样本空间为{正面,反面},基本事件数2,故正面朝上的概率为1/2。

  • 掷骰子:样本空间为{1, 2, 3, 4, 5, 6},基本事件数6,故掷出点数为3的概率为1/6。

  • 生日问题:一个班有50名同学,至少有两人生日相同的概率很高。我们可以计算所有人生日都不同的概率,然后用1减去它。计算表明,这个概率接近1。


条件概率与重要公式 🔗

上一节我们介绍了基础概率,本节中我们来看看当事件之间存在关联时,如何计算概率。

条件概率

条件概率是指在事件A已经发生的条件下,事件B发生的概率,记作P(B|A)。其定义为:

P(B|A) = P(A∩B) / P(A),其中P(A) > 0。

将分母乘到左边,得到概率的乘法定理:

P(A∩B) = P(A) * P(B|A)

例子:某游戏抽中五星卡的概率为0.6%,抽中五星卡时,抽到特定角色的概率为50%。则单次抽卡抽中特定五星角色的概率为:0.6% * 50% = 0.3%。

全概率公式

设B1, B2, …, Bn是样本空间S的一个完备划分(即它们互斥且并集为S)。则对任一事件A,有全概率公式:

P(A) = Σ P(Bi) * P(A|Bi)

这个公式将复杂事件A的概率,分解为在不同“场景”(Bi)下发生概率的加权和。

贝叶斯公式

贝叶斯公式描述了如何利用“结果”(A)的信息来更新我们对“原因”(Bi)可能性的判断。公式如下:

P(Bi|A) = [P(Bi) * P(A|Bi)] / Σ [P(Bj) * P(A|Bj)]

例子(核酸检测):假设人群感染率Q=1%,核酸检测假阴性率P=1%(即感染者有1%概率测为阴性),假阳性率为0。那么,一次检测结果为阴性的人,实际是感染者的概率是多少?

应用贝叶斯公式计算,这个概率约为0.01%。这说明在低感染率下,即使有假阴性,单次阴性结果仍有很高的可信度。


随机变量及其分布 📈

随机变量是将随机试验的结果映射为实数的函数。例如,抛硬币后,定义“正面得0分,反面得1分”,得分就是一个随机变量。

离散型随机变量

取值可数的随机变量。以下是几种重要的离散分布:

  • (0-1)分布:随机变量X只取0或1。P(X=1)=p, P(X=0)=1-p。

  • 二项分布:描述n次独立的(0-1)试验中成功次数k的概率。

    P(X=k) = C(n,k) * p^k * (1-p)^(n-k)

  • 泊松分布:二项分布当n很大而p很小时的近似。常用于描述单位时间内随机事件发生的次数。

    P(X=k) = (λ^k / k!) * e^(-λ),其中λ是单位时间内事件发生的平均次数。

连续型随机变量

取值充满某个区间的随机变量。由于取任一特定值的概率为0,我们使用概率密度函数(pdf) f(x) 和分布函数(cdf) F(x) 来描述。

F(x) = P(X ≤ x) = ∫_{-∞}^{x} f(t) dt

f(x) = dF(x)/dx (在F(x)可导的点)

以下是几种重要的连续分布:

  • 均匀分布:在区间[a, b]上,概率密度是常数。

    f(x) = 1/(b-a), for a ≤ x ≤ b

  • 指数分布:具有“无记忆性”,常用于描述等待时间。其概率密度为:

    f(x) = (1/θ) * e^(-x/θ), for x ≥ 0,其中θ>0为参数。

  • 正态分布(高斯分布):最重要的连续分布,由均值μ和标准差σ决定。

    f(x) = 1/(σ√(2π)) * e^(-(x-μ)²/(2σ²))


随机变量的数字特征 🧮

了解分布后,我们需要一些数值来刻画随机变量的核心特征。

数学期望(均值)

期望是随机变量所有可能值的加权平均,反映其“平均水平”。

  • 离散型:E(X) = Σ [xk * P(X=xk)]

  • 连续型:E(X) = ∫_{-∞}^{∞} x * f(x) dx

期望的性质

  1. E© = C (C为常数)

  2. E(CX) = C * E(X)

  3. 线性性:E(X+Y) = E(X) + E(Y) (无论X,Y是否独立)

  4. 若X,Y独立,则E(XY) = E(X) * E(Y)

方差与标准差

方差度量随机变量取值与其均值的偏离程度,记作D(X)或Var(X)。标准差是方差的算术平方根。

D(X) = E[ (X - E(X))² ] = E(X²) - [E(X)]²

方差的性质

  1. D© = 0

  2. D(CX) = C² * D(X)

  3. D(X+C) = D(X)

  4. D(X+Y) = D(X) + D(Y) + 2Cov(X,Y)

协方差与相关系数

协方差Cov(X,Y)度量两个随机变量的协同变化趋势。

Cov(X,Y) = E[ (X-E(X)) * (Y-E(Y)) ] = E(XY) - E(X)E(Y)

相关系数ρXY是标准化后的协方差,取值在[-1, 1]之间。

ρXY = Cov(X,Y) / [√D(X) * √D(Y)]

相关系数为0称为“不相关”。相互独立一定不相关,但不相关不一定独立(可能存非线性关系)。


大数定律与中心极限定理 ⚙️

本节我们来看看概率论中两个描述宏观规律的著名定理。

大数定律

大数定律描述了大量随机试验平均结果的稳定性。

  • (弱)大数定律:独立同分布的随机变量序列X1, X2, …, 其均值 X̄n = (ΣXi)/n 依概率收敛于数学期望μ。即试验次数足够多时,平均值几乎必然接近期望值。

  • 伯努利大数定律:是上述定律在(0-1)分布下的特例,即频率依概率收敛于概率。

中心极限定理

中心极限定理是概率论的基石之一。它指出,无论单个随机变量服从什么分布,只要满足一定条件,大量独立随机变量之和的标准化形式,其分布近似于标准正态分布。

  • 独立同分布中心极限定理:设X1, X2, …, Xn独立同分布,期望为μ,方差为σ²。则当n很大时,随机变量 Zn = (ΣXi - nμ) / (√n * σ) 近似服从标准正态分布N(0,1)。

    这意味着,许多微小、独立的随机因素叠加的总效应,往往呈现正态分布。例如,考试分数、测量误差等常服从正态分布。


总结 📝

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/d33b8ccc3d5f0c753a8f253fc090c6b4_2.png

本节课中,我们一起学习了概率论的基础知识。我们从概率的定义和古典概型出发,学习了条件概率、全概率公式和强大的贝叶斯公式。接着,我们引入了随机变量的概念,分别探讨了离散型与连续型随机变量的常见分布,如二项分布、泊松分布、均匀分布、指数分布和正态分布。然后,我们学习了刻画随机变量特征的数字工具:期望(均值)、方差、协方差和相关系数。最后,我们简要介绍了描述概率宏观规律的大数定律和中心极限定理。这些概念是理解图形学中许多基于概率的算法(如蒙特卡洛积分、路径追踪等)的必备基础。下一节课,我们将聚焦于概率论在图形学中的具体应用。

🎮 GAMES001-图形学中的数学 - P9:概率论(二)

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cce27c7778dda16750816a2f4b65f89c_1.png

概述: 本节课将探讨概率论在图形学中的应用,主要涵盖噪声和蒙特卡洛积分法。

1. 噪声

1.1 噪声的定义

  • 噪声是具有一定随机性的扰动或随机分布。

  • 在图像和视频中,噪声可以表示为具有一定随机性的扰动。

1.2 噪声的类型

  • 白噪声: 在一定频率范围内,所有频率的声音均匀混合。

  • 粉噪声: 低频强,高频弱。

  • 蓝噪声: 低频弱,高频强。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cce27c7778dda16750816a2f4b65f89c_3.png

1.3 噪声在图像中的应用

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cce27c7778dda16750816a2f4b65f89c_5.png

  • 图像量化过程中,由于显示设备限制,需要进行量化处理,这会导致图像细节丢失。

  • 通过添加噪声,可以模拟图像细节,提高图像质量。

1.4 噪声与图像量化

  • 有序抖动法:将图像像素值映射到3x3像素块,根据像素值大小决定块内像素值。

  • 随机抖动法:在图像像素值上随机添加噪声,然后进行量化处理。

  • 蓝噪声抖动法:使用特定算法生成蓝噪声,然后进行抖动和量化处理。

2. 蒙特卡洛积分法

2.1 蒙特卡洛积分法简介

  • 蒙特卡洛积分法是一种基于随机抽样的数值积分方法。

  • 通过随机抽样,可以近似计算积分值。

2.2 蒙特卡洛积分法的基本原理

  • 在积分区间内随机抽样,计算抽样点的函数值,然后对这些值进行加权平均。

2.3 蒙特卡洛积分法的应用

  • 求不规则图形的面积。

  • 求定积分。

  • 渲染算法中的采样。

2.4 重要性采样

  • 当函数值与概率密度函数形状相似时,蒙特卡洛积分的方差最小。

  • 重要性采样可以提高蒙特卡洛积分的效率。

2.5 拟蒙特卡洛法

  • 结合蒙特卡洛法和矩形法,提高蒙特卡洛积分的效率。

2.6 低差异序列

  • 低差异序列可以减少蒙特卡洛积分的方差,提高收敛速度。

2.7 随机数生成

  • 生成均匀分布的伪随机数。

  • 在单位球面上进行随机均匀采样。

总结

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cce27c7778dda16750816a2f4b65f89c_7.png

本节课介绍了概率论在图形学中的应用,包括噪声和蒙特卡洛积分法。通过学习这些内容,可以更好地理解图形学中的随机现象,并应用于实际问题的解决。

GAMES002-图形学研发基础工具—P1-Linux—shell—GAMES-Webinar—BV1cC411L7uG_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_0.png

概述

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_0.png

在本节课中,我们将要学习Linux操作系统和Shell的基础知识。这是图形学乃至整个计算机领域研发的重要基础工具。课程将从科研实践的意义引入,然后详细介绍Linux系统的概念、访问方式、Shell的基本操作、文件权限管理、包管理以及Shell脚本编写等内容。


https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_2.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_4.png

科研实践与工具的重要性

我是陈宝泉,来自北京大学。GAMES002这门课程由我和辛金瑞、叶开两位同学共同讲授。我首先开个头,因为这个课程与科研密切相关。

科研在大学里并非每位同学都会参与,它基于个人兴趣。对于大学生而言,科研常常显得神秘。因此,在北大,我们专门开设了一门教授科研实践的课程,旨在讲解科研是什么,并培养基本的科研能力。我们也安排了一些方法来加强同学们的科研训练。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_6.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_8.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_10.png

科研除了是大家了解的科学发现过程,实际上也是一种自我训练和能力培养的方式。对于以科研为职业的科学家而言,科研更是一种生活方式,它渗透到生活的方方面面。它培养我们如何思考问题、面对问题和解决问题。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_12.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_14.png

在本科期间,如果能够参与一定的科研实践活动,将非常有收益。我们这门课并非涵盖科研的方方面面,而是提供一系列实用的工具。我先介绍一下这门课的由来。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_16.png

科研工具的介绍是我们科研实践课的一部分。在北大,我开设并教授一门名为“科研实践”的课程,为期两个学期。第一个学期的课程内容主要分为几大块,让大家感受科研涉及哪些方面。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_18.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_20.png

课程内容主要分为三大块:

  • C1:科研方法。这部分主要由我来讲授。

  • C2:科研工具。要进入科研领域,可能需要先掌握一些相应的工具,才能更容易地上手。总的来说,就是降低科研门槛,让大家能够更顺畅地进入。

  • A:导师面对面交流。让同学们与一批科研导师交流,了解不同科研方向的问题。学生能够对不同研究领域和不同导师有很好的了解。这部分基本上是导师进课堂的方式,促进学生和导师之间形成一对一的交流。未来,学生可以选择去相关导师的实验室进行较长期的实习。

整个这一套方式,就是通过这样的内容,让大学本科的同学从大二开始,如果对科研想了解、想进入科研实践,能更方便一些。我们通过一门课的方式来做这样的连接。当然,如果没有这门课,这些元素你自己也可以去发现。导师也可以主动去联络。涉及到的科研工具,通过这门课也能有所了解。只要你主动、有意识,有没有这门课其实也没关系。

在讲授科研方法和素养方面,主要涉及以下内容:

首先,科研作为一种生活方式,我们需要在心理和心态上做好准备。在做科研之前,我们需要了解,做科研是有责任的,也涉及到科研道德等方面,需要提前有所了解。

当然,做科研的话,阅读能力很重要,阅读和写作科技论文或科技报告的能力很重要。怎么样培养这些能力?其实可以通过一些讨论、经验分享来实现。网络上也有很多相应的文章和经验分享,大家也可以有意识地了解。

还有一个特别重要的点就是科研交流。科研过程不是一个人关起门来闭门造车,它实际上需要不断地和别人去讨论、沟通。当你有了成果以后,也需要去展示你的成果。所以,如何做交流、如何做报告,这些都涉及到一些能力的培养。

在我们的课堂上,大概会有这样一些讨论主题。我可能会分享一些文章,例如针对图灵奖获得者Donald Knuth教授的一篇访谈,以及Richard Hamming写的一篇非常经典的报告《You and Your Research》。这个报告在网络上很容易找到,是一个非常经典的报告,阅读它的脚本总结应该可以获得很多收益。我们课堂上会分享这篇文章,并和大家一起讨论。

关于社会责任、科研伦理等方面,也有一些文章的阅读,大家也会在课堂上去讨论。作为各位,如果感兴趣,你也可以阅读相应的文章,和同学们互相讨论。可以主动在课外或兴趣小组中进行。

其他方面,如文献阅读、写作、沟通交流等,也有很多非常好的课件或资料,大家都可以去查找。我也列举了例如哈佛大学已故的Patrick Winston教授的一个非常经典的关于如何做报告的经验分享,非常值得去听一下。

第二部分就是我说的工具。在我们大学的课程学习当中,我们学到很多知识,但是面对科研,可能有一些工具并不在我们所学的课程中都覆盖了。像Python这样的东西还是覆盖了,但是有很多工具是没有被覆盖或没有讲到的,或者说没有足够的锻炼。这些东西有必要把它拎出来,我们来做这些分享。这也是我们GAMES002这门课的一个主要内容。

在总结这些内容的时候,一方面是我们同学们的平常总结,另一方面还有一个参考,就是MIT有一门课叫做《The Missing Semester of Your CS Education》。大概意思是,在你的CS课程中可能错过了一个小学期的内容。大家也可以去搜索、了解一些材料。

前面我说到了科研实践涉及的第三部分,其实就是具体要做科研,你要找到一位科研导师。因为你可能是对某一个方向感兴趣,那这个方向可能有不同的老师在做这方面的研究。寻找科研导师非常重要,因为导师有很多条件,不只是他有经验、能给你分享问题,另外在实验室还有一些条件、设备、计算资源等各个方面。同时,一般来说导师还有学生,比如研究生,他们也可以共同指导你。所以,寻找科研导师是个很重要的事情。

当然,你要实践。只有在实践当中,你才能更好地学习,学到真东西。这叫“Learn by Doing”,要边做边学,这样学得牢。这和课堂的学习非常不一样,所以这点也特别重要。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_2.png

主要就是这些。我们都知道“站得高,望得远”这句名言。如果你看得远,是因为你站在巨人的肩膀上。确实是这样,不管说是巨人还是多高的人,总的来说,你能站在他的肩膀上,就能够看得更远,这是非常重要的。我们每一个阶段的科研实践、经历,其实都是帮助我们不断站得更高,看得更远。所以,寻找这样的肩膀变得特别重要。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_4.png

这样的肩膀其实挺多的。除了我们经常可能认为的导师,其实还有很多,你都可以站在他们的肩膀上。例如:

  • 导师的合作者。不只是导师,还有导师的合作者,比如他来访问等。

  • 导师课题组的学长学姐。他们都能给你一手的经验或指导。

  • 你的同学。三人行必有我师,这一点都不假。所以,如果你有一个很好的同学团队,相互之间其实可以学到很多。

  • 来访的杰出讲者、学者。你还可以把眼界放开一点。

  • 国际会议上的同行。如果你后来慢慢能够去参加一些国际会议,那么在国际会议上就能认识到同行、领域里非常优秀的学者。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_22.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_24.png

一个很重要的事情是,如果你未来更多地投入到科研当中,你会发现每一个方向都会有它的一个社区(Community)。在国内,就是所谓的专业委员会,比如做图形的有图形方面的专业委员会。在国际上,ACM等都有相应学科方向的社区。当然,会议本身就构成了一个社区,一去参会,见到的都是你的同行。这样的同行就是一个社区,非常有意义。你都可以从他们身上学到很多经验。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_26.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_28.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_30.png

我特别强调在科研当中交流特别重要,就是各种各样的交流。当你有想法,或者想法不成熟的时候,你需要跟人家交流,把这个想法变得更清楚。当你有了一个比较清楚的想法,但是怎么解决,或者说提出一个很有意义的问题怎么去解决,你也需要跟大家交流。其实不是说你有成熟的想法和解决方案才去跟人家分享,不是这样的。分享是发现问题、发现解决方案的过程,它绝对不是最后结果的呈现。

所以,如果和本科生谈科研,或者说在我的科研实践课上,我应该用的最多的精力就是鼓励大家交流,帮助大家建立一个交流的意识。这其实非常非常重要。它和课堂的学习不一样,课堂学习就是你认真听讲,然后自己能够独立完成作业就很好。其实,即使在课程学习当中,交流也变得很重要。而且,我是鼓励随时随地的交流。

这里故意用了两张照片,其实就是说我们吃饭的时候也可以交流。吃饭的时候不只是说点娱乐、八卦,有些时候如果你在科研状态,其实也可以聊一聊科研中遇到的一些问题。可能在吃饭的时候突然有些灵感,在一种放松的状态。还有就是在走廊上碰着,我们叫“Hallway Conversation”。走廊上走着走着碰着,“我最近有什么好的想法跟你交流一下”,两人就聊上了。三言两语就把你脑子里面的问题描述一下。其实,所有这些都特别重要,对科研很有帮助。这样的一些小的行为,其实并不小。

如果说科研,那么我就说到,实际上做科研需要一个很好的环境,也需要一个好的文化。但你要说环境和文化可能是现有的,但是实际上,科研的环境和文化是每一个身处其中的人都能够参与去构建或改变的。这方面,我也特别愿意跟大家分享一下。

下面有几页PPT,也是我喜欢拿来讲述的。在我们科研的文化、意识上,有些时候我们需要打开我们的一些既有的思维和行为方式。这样的一些方式是对你的科研有益的。要打开这些方式,我们首先认识到一些不足,或者说有些对比。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_32.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_34.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_36.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_6.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_38.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_40.png

这里我借用了一位在德国的华裔女生用非常形象的插画(Illustration)来表达东西方文化的不同。这个还挺有点幽默性,然后又还挺形象。我可以分享几个,她做了好多。

她是说,我们首先生长的环境可能会不大一样。在我们的成长过程中,每个人从小朋友长大,得到的关注(Attention)可能会不一样。

然后,作为一个个人的自我认同、自我的认定和感受,在不同的社会文化环境下也会有所不一样。哪边是哪边,你们可以一眼就能感受得到。

还有就是说,我的导师、我的老板到底在这个群体中间是什么样的一个位置,它是不一样的。这个不一样也决定了你思维的时候,你是什么样的一个态度。你是不是能够主动地表达你的想法,是不是能够甚至挑战老师的或者有经验的人的想法或质疑,可能也都会多少会影响到。

当然还有我们的生活方式,就是你是什么都喜欢一个人行动,还是你喜欢独立的行动,还是说什么事情大家都一样,不要我跟别人不一样等等,这些也都是。

当然还有在一些交流、社交的场合,大家的可能行为方式也不一样。是大家围成一个圈比较有序,还是我很自由地去探索,三三两两,碰到熟人打个招呼等等。

这是一个比较形象的表达,不一定说那么准确,但是这样的一个对比,

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_8.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_42.png

也确实让我们意识到文化的不一样。这个当然就不多说了。

还有就是大家的社交关系等各个方面。还有就是说出现意见的时候,是直接的表达,还是通过很复杂的方式的表达。其实在科研上,我是建议大家能够直接地表达自己的想法,非常重要。

出现了问题,我们是直接去解决问题,还是绕过一些问题,还是说我们习惯性地绕开问题,还是我们习惯性地面对问题、解决问题,其实这都是一些从思维上的习惯。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_44.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_46.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_48.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_50.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_10.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_52.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_54.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_56.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_58.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_60.png

对这个就还有很多。这个女生还是挺有创造力的,很有创意,她有很多方面的插画。

榜样的力量或者说团体的力量很重要。各位同学如果有意进入到科研当中,你就要寻找同伴,寻找志同道合的人,也就是跟优秀的同学学习。这样的话,你就能够不断地形成你自己的一个群体。优秀的人互相之间学习,就可以更快的进步。这个其实也挺重要的。

在我实验室,我们有一个比较常态的本科同学来实习的传统。应该说,基本上每年我们都有本科同学参与实习。他从大二暑期可能正式开始,然后进入实验室做研究,最后他的研究成果也得到发表。就是有一批的同学都是这样。我就大概地来过一下:

  • 已经在读博士的吴仁迪同学。

  • 现在在读博士的李星宇同学。

这些都是在读博士,但是在他们的本科期间,这里显示的都是他们本科期间就发表的,像我们领域里SIGGRAPH的论文。

  • 当然还有万佩卓同学、温一佳同学、冠希同学、孙宇晨(现在都是在读博士)、徐文同学、刘文哲同学、叶开同学(就是我们这个课的老师之一)、金瑞同学(大家也看到他们的照片了,一会会见到真人)、陶凌霄同学。

这些都是在本科期间在实验室做科研实践。他们非常积极地参与科研,

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_62.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_64.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_12.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_66.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_68.png

也有一些成果。总的来说,科研还是一个很有意思的事情,它和课堂的学习还是不大一样的。我觉得本科阶段如果说你有兴趣,也能够去,也有精力进入到科研当中,当然就说大家能来上这个课,应该也是表明了同学们可能是对科研还是感兴趣,所以应该是个很好的开始。

总的来说,一个良好的心态做科研,在各个方面锻炼自己,跟导师打交道,跟同学打交道,跟学长学姐打交道,发现问题解决问题,怎么样平衡学习和科研,怎么样在你繁忙的学习之上又做科研,一个自己的时间安排、时间管理,还有你自己其他的很多的兴趣你也要去探索,各种事情之间的一个平衡等等。还有在这个科研实践、科研的当中,我前面提到的要跟人交流,要讲述自己的工作等等,其实是一个非常非常有益的事情。大家倒不是说把科研最后的结果先放在一边,这个过程本身是一个非常受益的。

所以,我就欢迎同学们加入到这个课程的学习当中,能够从这里开始,也是建立一个Community,然后未来能够享受科研。好吧,我的介绍就到这儿。接下来我就把这个麦克风交给金瑞同学,来对接下来的课程做介绍,然后开始我们这个课程正式的分享。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_70.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_14.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_72.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_74.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_76.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_78.png

谢谢大家。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_80.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_82.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_16.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_84.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_86.png


https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_88.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_90.png

课程安排与目标

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_92.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_94.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_96.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_98.png

好的,现在大家应该可以看到我的PPT的屏幕了。行好,也非常感谢陈老师的介绍。我在开始正式内容之前,先给大家介绍一下这门课的一些安排。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_100.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_102.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_104.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_106.png

我们这门课是GAMES002,名称叫做“图形学研发基础工具”。后面的课程将都由叶开和我来讲。如果大家有什么问题的话,这个PPT上有我们俩的联系方式(邮箱),可以给我们发邮件。

我们这门课有一个网站,网站地址和直播间的地址都在这里。时间就是从今天开始的每周二晚上,从晚上七点开始,一般来讲会讲一个小时左右。如果内容比较多的话,可能会讲到一个半小时。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_108.png

另外,我们这门课有一个QQ群,大家可以扫码加入一下。后续如果有什么问题,也欢迎大家在群里讨论。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_110.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_112.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_114.png

接下来我介绍一下作业的提交方式。我们有一个作业系统,大家可以点到第二个链接里面去注册一下。之后的作业就在这个作业系统里面提交。注册的时候,它会要求你填一下你的邮箱,请大家用自己的常用邮箱去注册,因为最终的奖品发放以及成绩评定都是跟你的邮箱相关的。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_116.png

OK,现在接下来内容可能会有点挡PPT,所以我就先把摄像头关一下。OK,现在应该可以看清楚。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_118.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_120.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_122.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_124.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_126.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_128.png

作业安排和评分有这样几条:

首先,我们这门课总共会安排大概四次作业,每次作业都是以书面报告的形式为主的。如果说某次课会留作业的话,就会在相应课程的末尾给出,提交入口也会在当日开放。今天我们是不会留作业的,但是下一周应该会留第一次作业。

所有作业以及作业系统注册的截止日期(DDL),都会设在这门课结课之后的一周。我们是在5月28号结课,所以这些DDL都设在了6月4号晚上23:59分。

后面是评分的一些要求。每次作业的占分比例会在布置时给出,不一定每次作业占比都一样。接下来我们会根据作业算一个总分,并进行排名。如果总分一样的话,就会按照提交的时间,如果提交得更快,就会把你排到更靠前的位置。奖品是待定的,大家可以期待一下。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_130.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_132.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_134.png

这门课程的目的主要有这么两点:

  1. 填补你专业课的空缺,能够学会使用工具来提升你的效率。我们学计算机的学生都知道,专业课其实并不会介绍太多工具怎么使用这种保姆级教程,顶多是给你丢一个链接让你自己去学。那我们这门课就是给大家稍微带一个引导,也不一定会讲得非常全面,但是可以作为一个引子,会提供一些资料,让大家不至于无从下手。

  2. 另外,就是希望大家如果能够在这门课之后,利用一些工具去更加提升你的科研效率或者你平时做事情的效率,那这门课就很成功了。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_136.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_138.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_140.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_142.png

需要注意一下,我们的授课对象是刚接触计算机或者图形学的学生。所以对一些大佬来讲,这个课程内容可能就会过于简单了。我们介绍的也都是一些很基本的、大家基本上都会日常大量运用到的工具。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_144.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_146.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_148.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_150.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_152.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_154.png

后面是我们这门课程的主要内容大纲。我们主要会讲九次课,时间是每周二,但是会在劳动节跳过一周。其中的前七节,其实跟图形学不一定直接相关,只要是计算机专业的,可能都会用到这些内容。后面两节课才是跟图形学更相关一些,会介绍图形学里面最常用的一些做科研需要用到的软件。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_156.png

我们这门课前几节有部分内容是参考MIT的一门课程,叫做《The Missing Semester of Your CS Education》。但是这个网站里面是全英文的,这个课件在课后也可以在网站上找到,这些链接都是可以点进去的。大家如果很好奇,就可以点进去看一下。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_158.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_160.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_162.png

好的,那我们就正式开始。稍稍等一下,如果大家有问题的话,可以在弹幕提出对课程安排上的问题。

(关于录播、证书等问题的解答略)

行,哦,看上去没有更多的问题了。好,没有更多的问题我就继续了。是这样的,因为我现在这个直播的设备不是特别方便看弹幕,所以大家如果有问题的话,尽量把问题攒到最后,讲完之后一起发弹幕。好吧,因为讲课过程中我也很有可能看不到你们弹幕,所以就大家凑合一下。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_164.png


https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_166.png

Linux系统介绍

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_168.png

接下来我们进入正式的内容。今天讲的是Linux和Shell。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_170.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_172.png

首先来介绍一下Linux系统的概念。Linux是一群开源的、基于Linux内核的类Unix操作系统集合。说起来比较绕,这里面主要有几个关键词:第一个是开源,第二个是Linux内核,第三个是类Unix,最后是一个操作系统的集合

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/cc822ac7b957dfe639cb014f1c1adaf8_174.png

  • 开源的意思就是说,Linux的核心代码你都是可以找到、可以使用的,如果你有条件也可以跑、也可以去修改它。开源社区你都是可以去做出一些贡献的,都没有问题。左侧的图片展示出来就是Linux这个系统它的代码的GitHub仓库。

  • 第二个词是Linux内核。什么叫内核呢?我们可以看右边这样一个图,一个分层的图。如果学过计算机操作系统的同学应该就会很熟悉。其实计算机系统可以理解为一层一层的抽象,一层抽象包着一层抽象,形成一种橘子皮不断往里剥,或者说是一种套娃的结构。

    • 最中心的部分是直接的硬件(Hardware)。

    • 直接控制硬件的外面一层叫做内核(Kernel),也叫系统内核。这些内核是直接跟硬件打交道的,所以可以想象这些内核其实是非常不适合让人类来直接操作的,它相当于像机器语言一样复杂。

    • 所以我们就需要再次对它进行一个封装,这个封装就到了Shell。Shell的中文意思其实就是一层“壳”,它是一层连接外界和内部的壳。它的作用就是和Kernel去打交道,打交道的方式就是通过一行行的命令行来去做的。你一般会打开一个Shell的窗口(一个终端窗口),然后输入一系列的命令,让计算机去做一些事情。这个窗口其实就是运行了一个叫Shell的程序。

    • 但是这个Shell也并不是我们

GAMES002-图形学研发基础工具—P2-Windows-cmd-PowerShell—GAMES-Webinar—BV1cC411L7uG_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_0.png

在本节课中,我们将要学习Windows操作系统及其两个常用的命令行工具:CMD和PowerShell。我们将了解Windows的基本概念、CMD和PowerShell的核心区别与使用方法,并通过实例演示帮助初学者快速上手。

Windows操作系统概述

上一节我们介绍了Linux系统及其Shell,本节中我们来看看Windows系统。Windows是由微软开发、经营和销售的一系列图形化操作系统家族。它与Linux最大的区别在于它不是开源的。

Windows操作系统家族主要分为以下几类:

  • Windows 9x系列:如Windows 95、98,以发布年份命名,现已非常古老。

  • Windows NT系列:NT代表“New Technology”,是现代Windows系统(如Windows 10/11)的内核基础。

  • Windows IoT系列:专为嵌入式设备和物联网设备设计。

  • Windows Server系列:安装在服务器上的Windows系统。

我们个人电脑上常用的系统,如Windows XP、7、10、11,都属于Windows NT家族。

为什么使用Windows?

以下是Windows系统的主要优点和应用场景:

  • 图形化界面强大:提供了非常直观和交互性强的用户界面。

  • 用户基数大,软件生态丰富:许多软件,尤其是在图形学领域,主要或仅支持Windows平台。

  • 兼容性强:在硬件和软件方面都有很好的兼容性。

  • 简单易用:图形化操作降低了使用门槛。

  • 应用场景广泛:在图形学研发和日常使用中极为常见。

访问Windows系统通常有以下几种方式:

  • 购买预装电脑:大多数品牌电脑已预装正版Windows。

  • 自行安装:购买系统后,使用启动盘进行安装。

  • 使用虚拟机:在现有系统(如macOS或Linux)上通过虚拟机软件运行Windows,常用于测试或运行来源不确定的程序,起到隔离保护作用。

CMD 与 PowerShell:核心区别

在深入用法之前,我们必须明确一个核心不等式:CMD ≠ PowerShell。它们是两个独立且设计理念不同的命令行工具。

  • PowerShell不直接执行CMD命令。你在PowerShell中输入CMD命令能工作,是因为PowerShell提供了“别名”机制,将一些PowerShell指令映射到了CMD命令的简写形式上。

  • PowerShell更强大。CMD能做的几乎所有事情,PowerShell都能做,反之则不然。

  • 设计理念不同

    • CMD:设计用于简单的批处理任务,如文件操作。其数据传递基于字符串。

    • PowerShell:是一种功能强大的脚本语言和Shell环境。它面向对象,可以在命令间传递结构化的对象,而不仅仅是文本。它支持复杂的脚本,并且跨平台。

总的来说,PowerShell在功能、可扩展性和现代性上远超CMD。但对于一些非常古老的Windows系统,可能只支持CMD。

启动与基础命令格式

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_2.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_4.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_6.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_8.png

大家可以跟随操作,启动电脑中的CMD或PowerShell。建议先启动CMD进行练习。

启动方法有多种:

  • 通过开始菜单搜索“CMD”或“PowerShell”。

  • Win + R 键,输入“cmd”或“powershell”后回车。

  • 在文件夹中,按住 Shift 键并右键点击空白处,选择“在此处打开PowerShell窗口”。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_10.png

CMD命令格式

CMD命令行的格式与Linux Shell相似:

命令 [参数1] [参数2] ...

参数可以是以下三种之一:

  1. 文件名

  2. 路径:Windows路径使用反斜杠 \ 连接,盘符开头(如 C:\Users)。虽然有时正斜杠 / 也能工作,但为保证兼容性,建议始终使用反斜杠。

  3. 选项:通常以斜杠 / 或减号 - 开头,用于修改命令行为。

例如,强制删除文件的命令为:

erase /f my_fault.txt

其中 erase 是命令,/f 是“强制执行”选项,my_fault.txt 是文件名参数。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_12.png

需要注意的是,CMD中空格和引号的规则不如Linux统一。例如,echo 命令会将后续所有内容(包括空格和引号)当作一个字符串原样输出,而在路径中包含空格时,又需要用引号将路径括起来。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_14.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_16.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_18.png

常用CMD命令对照表

以下是一些常用CMD命令及其类似功能的Linux命令:

| CMD 命令 | 功能简介 | 类似 Linux 命令 |

| :— | :— | :— |

| cd | 切换目录 | cd |

| dir | 列出目录内容 | ls |

| copy | 复制文件 | cp |

| move | 移动文件/重命名 | mv |

| del / erase | 删除文件 | rm |

| mkdir | 创建目录 | mkdir |

| rmdir | 删除空目录 | rmdir |

| type | 显示文件内容 | cat |

| find | 在文件中查找字符串 | grep |

| findstr | 使用正则表达式查找 | grep -E |

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_20.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_22.png

CMD同样支持输出重定向>>>)和管道|),其含义与Linux中相同。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_24.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_26.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_28.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_30.png

Windows权限与变量

用户账户权限

Windows账户主要分为三类:

  1. 管理员账户:拥有最高权限,可类比Linux的 root

  2. 标准用户账户:可正常使用计算机和程序,但无法更改系统设置或安装软件。

  3. 来宾账户:权限最低,仅用于临时访问。

要以管理员身份运行程序(类似Linux的 sudo),只需在右键点击程序(如CMD或PowerShell)时选择“以管理员身份运行”。

文件权限:访问控制列表(ACL)

Windows通过访问控制列表管理文件权限。它是“以文件为中心”的模型,即为每个文件维护一个列表,记录哪些用户能以何种权限访问它。

查看方法:右键点击文件 -> “属性” -> “安全”选项卡。

CMD中的变量

CMD中也可以使用变量,赋值时需使用 set 命令,引用时变量名需用百分号 % 包裹。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_32.png

赋值与查看

set MY_VAR=Hello
echo %MY_VAR%

修改环境变量(如PATH)

set PATH=%PATH%;C:\MyNewPath

删除变量

set MY_VAR=

查看所有变量

set

使用 set 设置的变量仅在当前CMD窗口有效。要永久修改环境变量,需使用 setx 命令或通过图形界面(右键“此电脑”->“属性”->“高级系统设置”->“环境变量”)进行设置。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_34.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_36.png

CMD脚本(批处理文件)

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_38.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_40.png

CMD脚本文件的后缀名为 .bat(batch的缩写)。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_42.png

创建与运行步骤:

  1. 新建一个文本文件,将其后缀名从 .txt 改为 .bat

  2. 右键点击该文件,选择“编辑”。

  3. 在打开的记事本中写入CMD命令。

  4. 保存后,双击文件即可运行,或在CMD中直接输入文件名调用。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_44.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_46.png

示例脚本:创建一个循环,生成一系列空文件。

@echo off
for /l %%i in (0, 1, 5) do (
    echo. > file%%i.txt
    echo. > text%%i.txt
)
  • @echo off:关闭命令本身的回显,使输出更简洁。

  • for /l ...:是一个循环结构。

  • %%i:循环变量。

  • echo. > fileecho.输出空行,> 重定向到文件,从而创建空文件。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_48.png

个人建议:对于复杂的自动化任务,学习使用 Python 脚本是更佳选择。Python跨平台、功能强大、生态丰富,在科研和深度学习等领域应用极广。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_50.png

PowerShell 深入浅出

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_52.png

现在,让我们深入了解更强大的PowerShell。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_54.png

Commandlets 与帮助系统

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_56.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_58.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_60.png

PowerShell的基本命令单元称为 Commandlet,其命名采用“动词-名词”格式,如 Get-ProcessSet-Variable,可读性很强。

  • Get-Verb:显示所有可用的动词。

  • Get-Command:列出所有内置的Commandlet。

  • Get-Help:获取帮助。例如 Get-Help Get-Command 可以查看 Get-Command 的详细用法。

命令格式与参数

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_62.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_64.png

PowerShell命令也支持参数,带名称的参数以减号 - 开头。

Get-Command -Name *Process

此命令会列出所有名称以“Process”结尾的Commandlet。* 是通配符,表示匹配任意字符。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_66.png

面向对象与管道

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_68.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_70.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_72.png

PowerShell是面向对象的。管道传递的是对象,而不仅仅是文本。使用 Get-Member 可以查看对象的属性和方法。

Get-Process | Get-Member

这条命令先获取所有进程对象,然后通过管道 | 传递给 Get-Member,从而显示进程对象的所有成员信息。

别名(Alias)

PowerShell通过别名机制兼容了许多CMD和Linux命令。使用 Get-Alias 可以查看别名映射。

Get-Alias gm

这会显示 gm 是哪个Commandlet的别名(结果是 Get-Member)。

Get-Alias -Definition Get-Member

这会显示 Get-Member 这个Commandlet有哪些别名。

PowerShell 脚本

PowerShell脚本文件的后缀名为 .ps1

创建和编辑方式与 .bat 文件类似。以下脚本实现与之前CMD脚本相同的功能:

for ($i=0; $i -le 5; $i++) {
    New-Item -Path "file$i.txt" -ItemType File
    New-Item -Path "text$i.txt" -ItemType File
}

运行脚本需要在PowerShell中执行,且通常需要指定路径:

.\script.ps1

注意:默认情况下,PowerShell可能禁止运行脚本。如果需要,可以管理员身份运行PowerShell,并执行 Set-ExecutionPolicy RemoteSigned 来修改执行策略(需谨慎)。

再次建议:尽管PowerShell非常强大,但对于大多数开发者和研究人员,Python 因其极致的跨平台性和在数据科学、机器学习领域的统治地位,通常是更优先的学习选择。

本节课总结

本节课中我们一起学习了:

  1. Windows操作系统:了解了其家族构成、优点以及访问方式。

  2. CMD与PowerShell的核心区别:明确了它们是不同的工具,PowerShell在功能和设计上更为先进。

  3. CMD基础:学习了命令格式、常用命令、变量操作以及如何编写简单的批处理(.bat)脚本。

  4. PowerShell基础:认识了Commandlet、面向对象特性、管道、别名机制,并了解了如何编写PowerShell(.ps1)脚本。

  5. 实用建议:对于自动化脚本任务,推荐使用 Python 作为更通用、更强大的工具。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/e4b79b1c08d99d4d7b35f4048b5b3299_74.png

通过本节学习,你应该能够在Windows环境下熟练使用命令行工具完成基本的文件操作和系统配置,并为后续的图形学开发工作打下基础。

GAMES002-图形学研发基础工具—P3-远程控制工具-命令行环境—GAMES-Webinar—BV1cC411L7uG_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_0.png

在本节课中,我们将学习如何使用远程服务器进行高性能计算,并掌握通过命令行环境进行远程控制的基础方法和工具。课程内容涵盖远程服务器的连接、文件操作、程序运行以及一些能提升效率的实用工具。

第一部分:远程服务器介绍 🚀

远程服务器,或称云服务器,是由服务供应商提供的远端计算设备。用户可以通过网络连接直接使用这些设备进行高性能计算,而无需自行管理和配置硬件。

在图形学与智能科学领域,最常见的云服务器是运行Linux操作系统的主机。这些主机通常具备强大的硬件配置,例如32GB以上的内存、多核CPU处理器以及用于密集CUDA计算的NVIDIA显卡。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_2.png

云服务器的来源主要有两种:

  • 一种是通过租赁方式,从腾讯云、阿里云、华为云等厂商按需(如按周、按月或包年)租用。

  • 另一种是科研实验室或个人自行购置服务器硬件,并自行维护,将其放置在固定地点(如实验室),然后远程连接使用。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_4.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_6.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_8.png

无论来源如何,我们都需要解决一个核心问题:如何从远程位置方便地使用这些服务器。这正是云服务器的意义所在——只要有网络,即可随时随地访问计算资源。

第二部分:远程控制基础方法 🔌

由于云服务器通常没有图形界面,我们需要借助命令行和一些辅助软件来完成操作。这主要包括终端的连接与退出、文件传输与管理,以及程序的运行与监控。

终端连接与退出

连接云服务器最基础的方式是通过SSH协议在终端中进行。无论是Windows还是Mac系统,通常都自带SSH命令。

连接命令的基本格式如下:

ssh -p [端口号] [用户名]@[服务器地址]

例如:

ssh -p 22 user@162.105.xxx.xxx

执行命令后,系统会提示输入密码或使用密钥进行身份验证。验证成功后,命令行提示符会从本地主机切换到远程服务器,表示连接成功。

要退出远程连接,有几种方式:

  • 主动退出:在远程终端中输入 exitlogout 或按下 Ctrl + D 组合键。

  • 被动退出:网络断开或连接超时会导致连接被远程主机关闭。

需要注意的是,直接关闭终端窗口或被动退出,会导致在该终端中运行的所有进程被终止。这对于需要长时间运行的任务(如训练神经网络)是不可接受的。

终端多路复用

为了解决终端退出导致进程中断的问题,我们需要使用终端多路复用工具,如 tmuxscreen。它们的主要功能是:在关闭远程连接后,原有进程仍能在后台继续运行,并且可以随时恢复查看。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_10.png

tmux 的核心概念包括:

  • 会话(Session):一个独立的终端工作环境。

  • 窗口(Window):会话中的一个标签页,一个会话可以包含多个窗口。

  • 窗格(Pane):窗口中可以进一步分割出的子区域。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_12.png

以下是 tmux 的基本操作示例:

  • 新建一个命名会话:tmux new -s session_name

  • 列出所有会话:tmux ls

  • 接入某个会话:tmux attach -t session_name

  • 在会话内,使用前缀键(默认 Ctrl + b)加命令键进行操作,例如:

    • Ctrl + b + d:断开当前会话(会话在后台继续运行)。

    • Ctrl + b + s:列出所有会话并切换。

通过终端多路复用,我们可以让程序在服务器后台安全地长时间运行。

文件传输与管理

我们经常需要在本地电脑和远程服务器之间传输文件,或在服务器上直接操作文件。

对于图形化操作,可以使用支持SFTP协议的软件,如 WinSCPXftp。它们提供类似资源管理器的界面,通过拖拽即可完成文件的上传和下载。

在命令行中,我们也可以使用一系列Linux命令进行文件操作,这在某些只有终端访问权限的情况下非常有用。以下是一些常用命令:

  • 列出目录内容

    ls          # 简单列出
    ls -al      # 列出详细信息(权限、所有者、大小等)
    
  • 查找文件

    find . -name "*.jpg"          # 查找当前目录下所有.jpg文件
    find /path -type f -name "*.txt" # 在指定路径查找.txt文件
    
  • 查看文件内容

    cat file.txt        # 显示整个文件内容
    less file.txt       # 分页查看文件内容(支持上下翻页)
    head -n 10 file.txt # 查看文件前10行
    tail -n 10 file.txt # 查看文件后10行
    
  • 统计空间

    du -sh *            # 统计当前目录下各文件夹大小
    df -h               # 查看磁盘剩余空间
    

这些命令组合使用,可以高效地完成文件查找、查看和空间管理任务。

程序运行与监控

在远程终端中运行程序与本地类似,直接在命令行输入程序名或脚本路径即可。

  • 运行与中断

    • 运行Python脚本:python train.py

    • 中断正在运行的程序:按下 Ctrl + C

    • 如果程序无响应,可以使用 kill 命令强制终止:先通过 ps aux | grep 程序名 找到进程ID(PID),然后执行 kill -9 PID

  • 查看运行状态

    • 查看所有进程:ps aux

    • 动态查看资源占用(类似任务管理器):top (按 q 退出)

    • 查看GPU使用情况:nvidia-smi

    • 查看内存使用情况:free -h

输入输出重定向与管道

这是Linux命令行中两个强大且核心的概念。

  • 输出重定向 >>>:将程序的输出结果保存到文件,而不是显示在屏幕。

    echo "Hello" > output.txt  # 将"Hello"写入output.txt(覆盖原有内容)
    echo "World" >> output.txt # 将"World"追加到output.txt末尾
    python script.py > log.txt 2>&1 # 将标准输出和错误输出都重定向到log.txt
    
  • 管道 |:将一个程序的输出作为另一个程序的输入。

    ps aux | grep python # 列出所有进程,然后筛选出包含"python"的行
    cat file.txt | wc -l # 统计file.txt的行数
    
  • 命令链 &&:只有前一个命令成功执行(返回值为0),才会执行下一个命令。

    make && ./program # 先执行make编译,如果成功,再运行./program
    

第三部分:远程控制工具 🛠️

对于初学者,直接使用命令行可能门槛较高。幸运的是,有一些集成了图形界面的远程控制工具可以大幅简化操作。

Visual Studio Code (VS Code)

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_14.png

VS Code 是一款强大的免费代码编辑器,通过安装 Remote - SSH 扩展,可以变身为一站式远程开发环境。

其优势包括:

  1. 无缝连接:在VS Code内直接连接远程服务器,界面与本地操作无异。

  2. 集成终端:在编辑器内直接打开远程服务器的终端。

  3. 文件管理:以图形化方式浏览、上传、下载、编辑远程文件。

  4. 插件生态:可以利用VS Code海量的插件(如代码高亮、智能提示、Markdown预览等)来增强远程开发体验。

配置步骤简述:

  1. 安装VS Code和 Remote-SSH 扩展。

  2. 点击左下角「远程连接」图标,选择「连接到主机」。

  3. 输入SSH连接命令(如 user@hostname),按提示操作即可。

其他工具

  • Xshell:一款功能强大的专业SSH客户端,提供标签式终端管理、丰富的安全功能等,但有商业许可限制。

  • MobaXterm (Windows):集成了终端、X11服务器、文件传输等多种功能的一体化工具。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_16.png

对于大多数用户,VS Code 的免费、开源、插件丰富和体验流畅等特点,使其成为入门和日常使用的首选。

第四部分:命令行环境详解 💻

当我们输入命令时,实际上是和 Shell(壳层)进行交互。Shell是用户与操作系统内核之间的桥梁,它解释我们的命令,并指挥系统执行。

命令行参数

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_18.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_20.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_22.png

在图形界面中,我们通过点击菜单和复选框来配置程序。在命令行中,则通过 命令行参数 来实现。

python train.py --data_dir ./data --epochs 50 --batch_size 32 --lr 0.001

上面的 --data_dir--epochs 等就是命令行参数,它们告诉 train.py 脚本应该如何运行。在编程时(如C/C++的 main(int argc, char *argv[]), Python的 argparse 库),我们可以解析这些参数。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_24.png

增强型Shell:Zsh与Oh My Zsh

默认的Bash Shell功能基础。Zsh 是一个功能更强大的Shell,而 Oh My Zsh 是一个社区驱动的、用于管理Zsh配置的框架,它提供了大量开箱即用的功能和主题。

安装Oh My Zsh后,你将获得:

  • 智能命令补全与历史:输入命令时按 Tab 键,可以自动补全命令、参数和文件路径。按上下箭头可以快速查找历史命令。

  • 目录快速跳转:输入目录的前几个字符,即可快速跳转,无需输入完整路径。

  • 丰富提示信息:在提示符中显示Git仓库状态、当前时间、虚拟环境名称等。

  • 海量插件:通过插件扩展更多功能,如语法高亮、自动建议等。

配置Zsh和Oh My Zsh通常只需几条命令,网上有丰富的中文教程可供参考。

总结 📚

本节课我们一起学习了远程服务器和命令行环境的核心使用技能。

我们首先了解了远程服务器的概念和用途。接着,深入探讨了远程控制的基础方法,包括通过SSH连接终端、使用tmux进行会话管理以保持进程运行、进行文件传输与操作,以及运行和监控程序。我们还介绍了强大的重定向和管道操作。

然后,我们看到了如何利用 VS Code 等现代工具,以更直观的图形化方式完成上述大部分操作,这极大地降低了初学者的入门门槛。

最后,我们解析了命令行环境的工作原理,并介绍了功能强大的 ZshOh My Zsh,它们能通过智能补全、历史记录和丰富提示等功能,显著提升命令行工作效率。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/db4b7d26241240f6ab253c6a3045f288_26.png

掌握这些工具和方法,你将能够高效、灵活地利用远程计算资源,为图形学及其他领域的研发工作打下坚实的基础。在实践中遇到问题时,善用搜索引擎和社区资源(如Stack Overflow、GitHub、相关QQ群),是快速成长的关键。

GAMES002-图形学研发基础工具—P4-Git-GitHub—GAMES-Webinar—BV1cC411L7uG_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_0.png

Git 简介

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_2.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_4.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_6.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_8.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_10.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_12.png

Git 是一个开源的分布式版本控制系统,用于跟踪文件的变化和版本管理。它最初是为 Linux 内核开发,但现在已经广泛应用于各种项目和协作中。

版本控制

版本控制是跟踪文件变化和版本的历史记录。它可以帮助我们:

  • 追踪文件修改:了解每个版本中文件的变化。

  • 回溯历史:在出现错误时,可以回溯到之前的版本。

  • 协作:允许多人同时工作,并合并他们的更改。

Git 功能

  • 版本管理:自动追踪每个文件的修改,并记录版本历史。

  • 差异比较:比较不同版本之间的差异。

  • 分支管理:创建和管理多个开发分支,以便并行工作。

  • 分布式协作:允许多人同时工作,并合并他们的更改。

Git 工作原理

Git 将项目目录分为三个部分:

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_14.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_16.png

  • 工作区:包含所有文件,可以直接编辑。

  • 暂存区:包含已修改但未提交的文件。

  • 版本库:包含所有提交的版本历史。

基本操作

  • git init:初始化一个新的 Git 仓库。

  • git status:查看当前工作区的状态。

  • git add:将文件添加到暂存区。

  • git commit:提交更改到版本库。

  • git log:查看提交历史。

GitHub 简介

GitHub 是一个基于 Git 的在线代码托管平台,提供以下功能:

  • 代码托管:存储和管理代码仓库。

  • 版本控制:跟踪代码更改和版本历史。

  • 协作:允许多人同时工作,并合并他们的更改。

  • 社区:与其他开发者交流和分享代码。

GitHub 功能

  • 代码克隆:从远程仓库克隆代码到本地。

  • 代码提交:将本地更改提交到远程仓库。

  • 分支管理:创建、合并和删除分支。

  • 代码审查:审查代码更改并提出反馈。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_18.png

多人协作

Git 支持多人协作,以下是一些关键概念:

  • 分支:独立的开发线,可以并行工作。

  • 合并:将一个分支的更改合并到另一个分支。

  • 冲突:当两个分支同时修改同一文件时,会发生冲突。

总结

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/1356cb8aa28b8e43bd0241364f4a9615_20.png

Git 和 GitHub 是强大的工具,可以帮助我们更好地管理代码和协作。通过学习 Git 和 GitHub,我们可以提高开发效率,并与其他开发者更好地合作。

GAMES002-图形学研发基础工具—P5-编译工具和包管理环境—GAMES-Webinar—BV1cC411L7uG_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_1.png

在本节课中,我们将要学习图形学研发中至关重要的两类基础工具:编译工具和包管理环境。我们将分别介绍C/C++的编译构建工具(如make、CMake、xmake)以及Python的包管理工具(如Conda、pip),并简要探讨性能探查的重要性。掌握这些工具将帮助你更高效地管理项目、处理依赖和优化代码。

编译型语言与解释型语言

上一节我们介绍了课程概述,本节中我们来看看编程语言的两大类型。C和C++是编译型语言,需要通过编译器将源代码转换为可执行的二进制文件。相比之下,Python等解释型语言则通过解释器实时将代码转换为机器码执行,虽然速度较慢,但带来了便捷性。

在Windows上,我们通常使用本地IDE(如Visual Studio)进行编译。然而,在服务器环境或需要跨平台协作时,我们往往需要通过命令行进行编译。一个简单的编译命令如下:

g++ main.cc -o main

这条命令使用g++编译器将main.cc源文件编译成名为main的可执行文件。

为什么需要构建系统?

直接使用命令行编译简单项目是可行的。但当项目变得复杂,例如需要链接第三方库(如OpenGL)时,编译命令会变得冗长且难以管理。此外,不同的机器可能安装了不同版本的编译器或库,导致相同的命令无法复现。

为了解决这些问题,我们需要使用构建系统。构建系统通过读取配置文件,可以在不同的操作系统和编译器环境下,自动化地完成编译、链接等任务。它还能智能地检测代码变更,只重新编译更新的部分,从而提高效率。

Make:基础的构建系统

在Linux环境下,最常用的构建系统之一是make。它通过读取名为Makefile的配置文件来执行构建任务。

一个Makefile文件的基本结构由目标、依赖和命令三部分组成。以下是其基本格式:

目标: 依赖项
    命令

例如,一个用于编译LaTeX文档的Makefile片段可能如下:

paper.pdf: paper.tex references.bib
    pdflatex paper.tex

这表示要生成paper.pdf,需要先准备好paper.texreferences.bib这两个文件,然后执行pdflatex命令。

对于之前那个简单的C++编译例子,对应的Makefile可以写成:

main: main.cc
    g++ main.cc -o main

make还支持一些特殊目标,例如:

  • make install: 将编译好的文件安装到系统路径。

  • make clean: 清理编译生成的文件。

常见的make用法包括:

  • make: 执行默认的构建任务。

  • make -j4: 使用4个线程并行构建以加快速度。

  • make -C build: 在build目录下执行构建。

然而,手动编写复杂的Makefile仍然非常繁琐,尤其是对于大型项目。

CMake:跨平台的构建配置工具

为了简化构建配置,我们通常使用CMake。CMake本身不是一个构建系统,而是一个构建系统生成器。它根据CMakeLists.txt配置文件,生成对应平台的原生构建文件(如Makefile或Visual Studio项目文件)。

一个典型的CMake使用流程如下:

mkdir build
cd build
cmake ..
make

首先创建一个独立的build目录以保持源码清洁,然后在该目录下运行cmake生成构建文件,最后使用make进行实际编译。

一个最简单的CMakeLists.txt文件示例如下:

cmake_minimum_required(VERSION 2.8)
project(HelloWorld)
add_executable(hello hello.cpp)

这段代码指定了CMake最低版本、项目名称,并声明从hello.cpp生成一个名为hello的可执行文件。与手写Makefile相比,CMake自动处理了许多编译细节。

使用CMake管理多文件项目

当项目包含多个源文件时,CMake可以方便地管理编译和链接。例如,一个项目包含sqrt.cpp(定义函数)和main.cpp(主函数),CMakeLists.txt可以这样配置:

cmake_minimum_required(VERSION 2.8)
project(MyProject)
add_library(sqrt_lib sqrt.cpp)
add_executable(main main.cpp)
target_link_libraries(main sqrt_lib)

这里,add_librarysqrt.cpp编译成库,add_executable创建可执行文件,target_link_libraries将两者链接起来。

使用CMake查找和链接第三方库

对于第三方库,CMake提供了find_package等命令来简化配置。例如,查找并链接Eigen库(一个只有头文件的库):

find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})

find_package会查找系统中安装的Eigen3,并设置相关变量(如EIGEN3_INCLUDE_DIR),我们只需将其包含到头文件路径中即可。

此外,还可以结合Vcpkg等跨平台包管理器。安装库后,Vcpkg会提供对应的CMake配置语句,直接复制到你的CMakeLists.txt中即可使用。

xmake:现代化的构建工具

xmake是一个集构建、包管理于一体的现代化C/C++构建工具。它使用Lua脚本作为配置文件,语法更加简洁直观。

一个基础的xmake.lua配置文件如下:

target("hello")
    set_kind("binary")
    add_files("src/*.cpp")

这四行代码就定义了一个从src目录下所有.cpp文件生成可执行文件的目标。xmake还内置了包管理、编译器管理等功能,并且兼容Vcpkg。它甚至可以直接生成Visual Studio项目:

xmake project -k vs2019

运行构建也极其简单:

xmake

xmake的设计更符合现代开发习惯,但在生态和复杂场景支持上可能不如CMake成熟。

构建工具对比与选择

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_3.png

我们来总结一下这三种工具:

  • make:基础,配置灵活但繁琐,了解其概念即可。

  • CMake:当前事实标准,跨平台能力强,是发布项目的首选。

  • xmake:新兴工具,配置简单,集成度高,适合快速上手和个人项目。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_5.png

对于初学者,建议从CMake学起,它是目前最流行、资源最丰富的工具。

Python包管理与虚拟环境

讲完了C/C++的编译,我们来看看Python的包管理。Python作为解释型语言,没有编译环节,核心在于管理第三方包和环境。

Conda是一个强大的包管理和环境管理工具。MiniConda是它的一个轻量级发行版。安装后,默认会有一个base环境。

为了提高国内下载速度,建议配置清华源等国内镜像。配置好后,基本的包管理命令如下:

conda install package_name        # 安装包
conda install package_name=1.0    # 安装指定版本
conda remove package_name         # 卸载包
conda list                        # 列出已安装包
conda clean -a                    # 清理缓存

另一个常用的包管理工具是pip,其命令与Conda类似:

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_7.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_9.png

pip install package_name
pip install -r requirements.txt   # 根据文件安装
pip uninstall package_name
pip list

虚拟环境

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_11.png

虚拟环境是Python开发中的核心概念。它是一个独立的目录,包含特定版本的Python解释器和一套软件包。不同项目可以使用不同的虚拟环境,从而避免包版本冲突。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_13.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_15.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_17.png

使用Conda创建和激活虚拟环境的命令如下:

# 创建名为myenv的虚拟环境,并指定Python版本
conda create -n myenv python=3.9
# 激活环境
conda activate myenv
# 退出当前环境
conda deactivate

你也可以指定虚拟环境的安装路径,以节省系统盘空间。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_19.png

在实际开发中,我们经常需要复现别人的项目。通常项目会提供一个requirements.txt文件,列出了所有依赖包及其版本。我们可以按以下步骤设置环境:

conda create -n project_env python=3.8
conda activate project_env
pip install -r requirements.txt

注意:尽量避免在同一个Conda环境内混用conda installpip install,以免引起依赖冲突。建议主要使用其中一种。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_21.png

性能探查简介

最后,我们简要探讨一下性能探查。无论是C++还是Python项目,优化代码性能都是重要的一环。性能探查工具可以帮助我们定位代码中的瓶颈。

对于C/C++项目,可以使用IDE自带的性能分析器(如Visual Studio Profiler)。它会以表格或图表形式展示各个函数的CPU时间占比,帮助你找到最耗时的部分。

对于Python项目,可以使用内置的cProfile模块,或者结合第三方可视化工具(如snakeviz)。cProfile可以生成详细的性能报告,而line_profiler工具甚至能分析到每一行代码的执行时间。

例如,通过性能分析,你可能会发现某一行检查元素是否在列表中的代码if item in my_list:占用了93%的时间。这提示你,对于频繁的成员检查,应该使用集合set而不是列表list,因为集合的查找时间复杂度是O(1)。

性能探查的意义在于:在开发初期,我们应优先关注实现功能的正确性和开发效率;在功能稳定后,再利用性能工具进行优化,从而在长期迭代中节省大量时间。

高效编码实践建议

从性能探查引申开来,以下是一些高效编码的实践建议:

  1. 准备与阅读代码库:利用IDE的跳转、调试功能阅读他人代码,不要只当纯文本阅读。

  2. 快速起步与验证:初期使用最高效的方法(如Jupyter Notebook)验证想法,快速迭代。

  3. 延迟优化:先确保功能正确,再使用性能分析工具进行优化。

  4. 善用调试工具:使用IDE进行交互式调试,必要时保存中间结果与标准输出对比。

  5. 记录与计划:记录实验参数,明确开发计划和瓶颈,平衡时间与精力。

总结与作业

本节课中我们一起学习了图形学研发中的核心工具。我们介绍了C/C++的构建系统演进:从基础的make,到广泛使用的CMake,再到新兴的xmake。我们也探讨了Python的包管理工具Condapip,以及虚拟环境的重要性。最后,我们简要了解了性能探查的意义和基本方法。

掌握这些工具,将为你后续的图形学项目开发打下坚实的基础。


作业二

本次作业共22分,其中6分为选做。

第一题(8分):请在A(C++)和B(Python)中任选一题完成。

  • A (C++):编写一个简单的“Hello World” C++程序,并为其编写一个CMakeLists.txt文件,使其能够通过cmakemake命令成功编译运行。

  • B (Python):安装MiniConda或Anaconda。创建一个新的虚拟环境(例如名为test_env),在该环境中使用pip安装numpymatplotlib包。最后,列出该环境下所有已安装的包,并截图。

第二题(8分):请在A(C++)和B(Python)中任选一题完成。

  • A (C++):实现一个简单的排序算法(如冒泡排序)。生成一个包含大量随机整数的数组,对其进行排序,并记录排序时间。尝试使用性能分析工具(如gprof或IDE内置工具)分析代码热点。

  • B (Python):实现一个简单的排序算法。生成一个包含大量随机整数的列表,对其进行排序,并记录排序时间。使用cProfile模块分析代码性能,并简要说明分析结果。

第三题(选做,6分)

  • A (C++):尝试使用xmake构建一个简单的C++项目,体验其配置和构建过程。

  • B (Python):尝试更复杂的虚拟环境操作,例如:导出当前环境的requirements.txt文件;根据该文件在另一个新环境中复现安装;使用conda env remove删除一个虚拟环境。

提交要求:将代码、命令、运行结果截图等内容整理到一份PDF文档中提交。

截止时间:6月4日晚上。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/dc4d384c90960476ff4c33fac7f6cbf8_23.png

如有疑问,请参考课程主页加入QQ群进行讨论。

GAMES002-图形学研发基础工具—P6-代码编译器与笔记软件使用技巧—GAMES-Webinar—BV1cC411L7uG_note

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_0.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_2.png

在本节课中,我们将学习两类在图形学研发中至关重要的工具:代码编辑器和文档写作工具。我们将详细介绍 Vim、Visual Studio Code、Markdown 和 LaTeX 的核心概念与基本使用方法,帮助你提升开发与写作效率。

集成开发环境概览

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_4.png

集成开发环境的主要功能是提供一个编写代码的平台,并集成了编译、运行、调试等其他工具。

以下是截至2023年最热门的集成开发环境用户数量统计。Visual Studio Code 处于断层第一的位置,用户基数最大。同为微软开发的 Visual Studio 排名第二,它是一个功能更强大、更完整的集成开发环境。今天要介绍的 Vim 也较为常见,排名靠前。此外,PyCharm 和 Jupyter Notebook 是 Python 开发者常用的专业工具。

以下是常用代码编辑器对用户的吸引力统计图。每个扇形代表一个代码编辑器,每条半透明的边代表用户正在使用 A 但对 B 感兴趣的数量。边越粗,代表数量越多。我们可以主要关注 Visual Studio Code、Vim 和 Neovim。Neovim 是 Vim 的更新版本。

从 Visual Studio Code 指出的边代表用户正在使用它但对其他软件感兴趣。指向 Visual Studio Code 的边代表用户正在使用其他软件但对它感兴趣,也包括只对它感兴趣的高粘性用户。

更有意思的是 Neovim。从 Visual Studio Code 指向 Neovim 的边代表用户正在使用 Visual Studio Code 但对 Neovim 感兴趣。而所有使用 Neovim 的用户都只对自己这一个软件感兴趣,不会去看其他的。可以看出,习惯使用 Vim 这类风格编辑器的用户,可能很难接受其他编辑器。Vim 只有一条较细的边指向 Visual Studio Code,这是因为 Visual Studio Code 可以配置成与 Vim 操作几乎一样,所以还能符合 Vim 的操作习惯。

Vim 编辑器 🧑‍💻

上一节我们介绍了集成开发环境的概况,本节中我们来看看经典的命令行编辑器 Vim。接下来的内容适用于 Neovim 和 Vim。

介绍 Vim 有两个目的。第一,如果你对 Vim 非常感兴趣,欢迎你以本 PPT 为引子,继续查阅文档并尝试熟悉它。需要提醒的是,Vim 的学习过程可能很困难,会很慢。第二,对于对 Vim 不感兴趣的同学,你们需要了解几点。第一是 Vim 的模式,它就像一个五状态的自动机,你们要清楚状态之间如何切换。第二很重要,你们要知道打开 Vim 后如何退出。如果完全不会使用,有时可能避免不了打开 Vim,那时如果连退出或保存都不知道怎么做,就会陷入很麻烦的困境。

Vim 的特点是使用广泛且历史悠久。它比图形化界面的操作系统历史还要悠久,可以完全运行于命令行,也只能运行于命令行。例如,现在远程 SSH 连接到一个没有图形化界面的服务器时,大概率要用到 Vim。当然也有一个更接近现代编辑器的叫做 Nano,功能不如 Vim 强大,但可能更接近现在的编辑器。Vim 确实非常难以学习,但如果能熟练使用,收益非常高。一般来讲,使用 Vim 的用户开发速度和打字速度都会比使用其他软件的开发者快一些,效率要高一些。

Vim 还有一个大特点,就是它可编程,有高度的自由性,可以进行高度的个性化配置。可配置的东西包括但不限于重映射键盘、设置习惯的快捷键、以及高亮和缩进等规则。Vim 的配置文件类似于之前讲过的 Bash 的 .bashrc,Vim 也有一个叫做 .vimrc 的东西。如果是 Neovim,会不太一样,它叫做 init.vim。总之,一些更高级的设置都可以在配置文件里设置。另外,Vim 也会借助大量第三方插件来实现编辑文本之外的功能。

在此之前,需要让大家看一下并记住右下角这样一张图。这个图代表 Vim 有五种状态。最常用的状态也是 Vim 刚打开时所处的状态是中间的 Normal 模式。在 Normal 模式下,键盘上敲入的字符不会直接插入,而是被识别成命令,作为自动机转换的转移条件。例如,敲一个大写的 R,就会从 Normal 切换到 Replace 状态。Replace 状态主要是用来替换一段长文本的。还有一个 Insert 状态,最接近现代文本编辑器的常态。在 Insert 状态下,输入字符会真正在光标处插入字符,像正常编辑文本一样。右下角的是 Visual 状态,用于选择一段文本,好比用鼠标框选一段内容。还有一个叫做 Command Line 状态,即命令行模式。在这个状态下,可以输入字符,这些字符会被解析成命令,让 Vim 编辑器去做指定的事情。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_6.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_8.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_10.png

Normal 模式

我们接下来一个状态一个状态来讲。首先是 Normal 模式。

在 Normal 模式下,上下左右移动可以用 KJHL 这四个键代替。大家可以看一下键盘上 HJKL 是连续一排的四个键,这与上下左右键的分布不太一样。使用这四个键移动是因为 Vim 的宗旨是尽可能不用鼠标,并让你尽可能少用键盘上不易触及的区域。它让你所有工作都能在数字键、常规字母键、ESC 以及一些普通快捷键(如 Shift、Control)这些手指最容易够到的地方完成。使用旁边的小数字键或上下左右箭头被认为是浪费时间。这就是 Vim 的哲学之一。另外两个哲学是区分模式和高度可配置。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_12.png

在 Normal 模式下,是用 HJKL 这四个键进行光标移动的。不只有这四个基础移动,还有其他花式跳转,例如跳到单词的开头结尾、括号的左半部分和右括号、行内段落间或上下翻页等。现代编辑器里的高级功能 Vim 里都有,它们对应 Normal 模式下的不同按键。具体按键在 PPT 里有讲,不一一念了,大家可以在课后看一下,也可以照着实践一下。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_14.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_16.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_18.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_20.png

Insert 模式

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_22.png

接下来介绍 Insert 模式,即插入模式。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_24.png

进入插入模式的方法是在 Normal 模式下按小写 i 键。进入 Insert 模式后,做的事情就是在当前光标位置进行编辑。还有一些其他花式进入 Insert 模式的方法,例如先跳到行首再进入 Insert 模式,实现方法是用大写的 I,即 Shift + I。还有一些其他先移动光标再进入 Insert 模式的方式也在 PPT 里。此外,有一些比较简单的文本修改,可以不需要进入 Insert 模式,只在 Normal 模式下完成。例如,在 Normal 模式下按小写 s 是删除当前字符再进入 Insert 模式。等价的按小写 x 操作是只会删除当前字符,不会进入 Insert 模式。类似还有一些其他按键可以让你更快地进行简单编辑操作,无需模式切换。

Replace 模式

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_26.png

还有一个 Replace 模式,按大 R 进入。它主要用于长文本的替换,这里没有详细介绍,因为它确实不是一个很常用的模式。一般我们最常用的模式还是 Insert 模式,用来编辑文本。

Visual 模式

接下来要介绍的是 Visual 模式,即 Vim 里的选择文本。

在 Visual 模式下,用移动键(包括上下左右键以及在 Normal 模式下的高级移动键)移动光标,光标移动道路上会框选住所有经过的文本。进入 Visual 模式有三种方式。第一种是按小写 v 进入,代表移动光标经过的字符被选中。如果按大 V 进入,相当于是光标经过的行整行都被选中。如果是 Ctrl + V 进入,它就是列选择模式。

在选中之后还处在 Visual 模式时,可以有两种选择。一个是按 y 表示复制选中的内容。按 y 之后,Visual 模式将退出,回到 Normal 模式。剪切 d 也是同理。在复制或剪切完之后,回到 Normal 模式,再按一下 p 就可以在当前光标位置进行粘贴。

我们可以稍微比较一下 Vim 的操作和现代文本编辑器的操作。现代文本编辑器如果我想复制一段话到文本的开头,就是用鼠标框选住一段话,然后按 Ctrl + C,再用鼠标点一下开头,然后 Ctrl + V。如果不想用鼠标,就是用上下左右键先移动到想框选的位置,把它框选住,然后 Ctrl + C 完后,可以按一下 Home 键或 Ctrl + Home 键回到整个文档的开头,再按下 Ctrl + V 进行粘贴。但是在 Vim 里面,首先需要在 Normal 模式下把光标移动到框选的开始位置,然后进入 Visual 模式,移动光标直到把所有想复制的文本都框选下来,再按一下 y,然后退回 Normal 模式。在 Normal 模式下,再移动光标到文本的开头,这个时候再按一下 p。这就是 Ctrl + CCtrl + V 的全部过程。所以 Vim 与平时操作的一个最关键区别在于,平时的快捷键是通过一系列组合键来实现复杂性,而 Vim 的复杂性在于状态机,在于模式之间的切换。所以你会看到熟练使用 Vim 的人经常会把 ESC 敲烂,因为他们经常需要回到 Normal 模式。最常用的回到 Normal 模式的按键就是 ESC

Command Line 模式

最后一个 Vim 的状态叫做命令行模式。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_28.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_30.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_32.png

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_34.png

命令行模式是通过在 Normal 模式下输入冒号 : 进入的。命令行模式会在整个终端窗口的最下面一行显示一行,开头是冒号,接下来输入的所有字符都会在冒号后面显示。这一串字符会被解析成你要 Vim 干的指令。最常见的命令有几个,接下来的命令是大家需要记住的,即使你不使用 Vim 也要记住这些。

https://github.com/OpenDocCN/cs-notes-pt3-zh/raw/master/docs/games/img/2ee207ee34ca6bea7cfaec27b01e3c77_36.png

首先,输入 w 再回车,表示保存文件。w 后面跟一个叹号 !sudo %,意思是用 sudo 权限去保存文件。也就是说,如果你没有以 root 身份打开 Vim,而你又编辑完了文本,不想退出再重新编辑,可以用这个方式,用 root 权限直接去保存。还有这三个是等价的:wqx、大写的 ZZ 都是保存并退出的意思。q! 和大写的 ZQ 表示的是退出但不保存。上面这四条大家需要记住,即使不用 Vim,也要记住,这样至少知道怎么保存、怎么退出。接下来后面这些是一些更高级的命令,大家自己看就可以了。

Visual Studio Code 编辑器

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐