第 2 章 向量 (Vectors)
核心结论
-
向量有数学与几何两套等价定义:数学上 = 数字的有序列表,几何上 = 有向线段(只有大小与方向,没有位置);3D 数学侧重几何解释。
-
向量与点的根本区别:向量描述 位移("从这里到那里"),点描述 绝对位置;向量相等只看大小与方向不看起点。
-
基本运算:取反、数乘、加减——都按分量独立运算,几何上对应方向翻转 / 拉伸 / 平移拼接;平行四边形与三角形法则是几何直觉来源。
-
大小与单位向量:magnitude \(\|\mathbf{v}\|\) 用毕达哥拉斯推广;单位向量 \(\hat{\mathbf{v}} = \mathbf{v} / \|\mathbf{v}\|\) 是"只保留方向"的工具,规范化 (normalize) 是后续投影 / 光照 / 物理单位化的前置步骤。
-
点积 (dot product):把两个向量的"对齐程度"折成标量;几何意义 = 一个向量在另一个向量上的 有符号投影长度;代数实现 = 对应分量乘积之和。点积是光照、夹角、相似性、矩阵乘法的源头。
-
叉积 (cross product):仅限 3D;结果是同时垂直于两个输入向量的向量;大小 = 平行四边形面积、方向 = 由 手性 决定(左手系顺时针朝你 / 右手系逆时针朝你);叉积是法向量与"判断顺逆时针"的核心工具。
|
本章主旨
本章是 3D 数学的"积木章"——把上一章的笛卡尔坐标系具象化为可运算的对象。围绕 6 个核心概念:向量本身、向量 vs 点、基本运算、长度 / 单位向量、点积、叉积。点积与叉积是后续矩阵乘法、变换、旋转、光照、碰撞检测的几何底座,所有 3D 引擎 API 都把这两个运算暴露为内建函数。 |
一、核心概念
本章围绕 6 个核心概念展开:从向量的两套等价定义出发,明确"向量 ≠ 点",建立基本运算,再深入到大小 / 单位向量,最后是点积与叉积这两个核心几何算子。
| 概念 | 定义 + 重要性 | 实现提示 |
|---|---|---|
向量的两套定义 |
数学:有序列表 |
C++ 用 |
向量 vs 点 |
向量描述相对位移,没有绝对位置;点描述绝对位置,没有方向。两者都用 |
把点的位置当向量用会产生"为何这里也能正确计算方向"的混淆;明确区分通常用类型 |
基本运算:取反 / 数乘 / 加减 |
取反 |
§2.7 加减;§2.6 数乘;§2.5 取反。三角形法则 / 平行四边形法则是几何直觉;C++ 中用重载 |
大小与单位向量 |
magnitude |
§2.8 大小;§2.9 单位向量;§2.10 距离公式 |
点积 (dot product) |
代数 |
§2.11;点积的几何意义比公式更重要("印在手背上")。点积是判定方向一致 / 相反 / 垂直的最快工具,也是 Lambert 光照 |
叉积 (cross product) |
仅 3D;结果向量同时垂直于两个输入;大小 |
§2.12;叉积是求三角形 / 多边形法向的唯一通用方法(无 4D 版本)。手性差异决定叉积的"朝向"——跨引擎时务必先校准。 |
二、详细笔记
2.1 向量的两套定义 (Mathematical & Geometric Vectors)
What:数学上向量是有序数字列表,几何上向量是有向线段(箭头)。
Why:3D 数学必须在两种视角间切换——代码写的是分量运算,几何想的是箭头与方向;不理解两者的等价性,会卡在"为什么这条公式对应那个图"。
How:
-
数学定义:向量是 \(n\) 元有序列表 \(\mathbf{v} = [v_x, v_y, \ldots, v_n\)],可写成行向量或列向量(行 vs 列在 §4.1.7 才显出差异)。标量 = 1D 向量。
-
几何定义:向量 = 有向线段 = 大小(长度) + 方向;可以画在图上任意位置("平移不改变向量"),但 没有 绝对位置。
-
约定记号:本书用粗体小写 \(\mathbf{a}, \mathbf{b}, \mathbf{u}, \mathbf{v}\);标量用斜体小写
a, b, x, θ, α;矩阵用粗体大写 \(\mathbf{A}, \mathbf{B}, \mathbf{M}, \mathbf{R}\)。
|
向量库对记号的映射
3D 编程时建议用类型区分:标量 |
When:所有 3D 几何问题;不适合用向量表示"颜色 / 索引 / 概率"等非几何量。
Example:位移 \("向东 3 步"\) = \(\mathbf{d} = [3, 0\)];速度 \("东北 50 mph"\) = \(\mathbf{v} = (50/\sqrt{2}, 50/\sqrt{2})\)。两者都没有位置,只有方向与大小。
2.2 向量 vs 点 (Vectors vs Points)
What:向量描述相对位移,点描述绝对位置;两者数值表示相同但语义不同。
Why:把点当向量用会丢失"位置"语义;把向量当点用会丢失"位移"语义——例如 PointA + VectorAB = PointB 合理,但 Vector + Vector = Vector(相对位移叠加),而 Point + Point 无意义。
How:
-
向量:唯一刻画"相对位移",可在图上平移而不改变身份。比较两个向量只看大小 + 方向,与起点无关。
-
点:唯一刻画"绝对位置",坐标系一变就失效。
-
关联:点 \(\mathbf{P}\) 与向量 \(\mathbf{v}\) 的"分量相同"是巧合——向量可在任意位置画出,点是固定的位置。
-
运算合法性:仅
Point + Vector = Point/Point − Point = Vector/Vector ± Vector = Vector/Vector · Scalar = Vector是合法的;Point + Point与Vector + Point均 无意义。
When:建模"刚体位置"用 Point3(带父变换);建模"速度 / 加速度 / 方向"用 Vec3;动画系统中两者频繁互转("从父空间位移 = 子空间位置 − 父空间位置")。
Example:P + v = Q 表示"在 P 点出发,沿 v 移动到达 Q 点";若把 P 当向量而 v 是点,则该公式在几何上无意义。
2.3 基本运算 (Negation, Scalar Multiplication, Addition, Subtraction)
What:四种基本运算——取反、数乘、加法、减法——按分量独立执行,几何上分别对应方向翻转、长度缩放、平移拼接、相对位移。
Why:所有后续高级运算(点积、叉积、矩阵乘法)都是这些基本运算的组合;理解几何直觉可避免"公式对结果反"的常见错误。
How:
取反(§2.5):
几何上:方向反向、大小不变。
数乘(§2.6):
k > 0:方向不变、大小乘 |k|;k < 0:方向反向 + 大小乘 |k|;k = 0:零向量。
加减(§2.7):
几何上:三角形法则(首尾相接)或 平行四边形法则(同起点);a − b = a 末端到 b 末端的位移。
|
几何法则的速记
|
When:位移叠加、合力 / 合速度计算、参数化曲线(§13 章 Bezier 等);所有"多个量合成为一个量"的场景都从加减出发。
Example:向量 a = [3, 1]、b = [−1, 2],则 a + b = [2, 3]、a − b = [4, −1]。
2.4 大小与单位向量 (Magnitude & Unit Vectors)
What:向量的"长度"由 magnitude 给出,单位向量是 magnitude = 1 的"纯方向"向量。
Why:法线 / 光照方向 / 相机正交基必须用单位向量;规范化 (normalize) 是几乎所有 GPU 着色器、刚体动力学、相机控制的前置步骤。
How:
magnitude(§2.8):
即 3D 毕达哥拉斯定理。
距离公式(§2.10):
几何意义:两点间直线长度。
单位向量(§2.9):
规范化前置检查:必须 ‖v‖ > 0,否则除零。
|
零向量既不正交也不平行
点积把零向量视为"与所有向量垂直",叉积把零向量视为"与所有向量平行"。两者都仅是 运算结果 的一种解释,零向量本身既无方向也谈不上垂直 / 平行。 |
When:法线 (surface normal)、光照方向 (n · l)、相机正交基(forward / right / up)、旋转矩阵的列向量。
Example:v = [3, 0, 4] ⇒ ‖v‖ = 5 ⇒ v̂ = [0.6, 0, 0.8]。GPU 着色器通常用 normalize(v) 内建函数自动除零保护。
2.5 点积 (Dot Product)
What:点积 a · b 把两个向量的"对齐程度"折成标量;代数上是分量乘积之和,几何上是 有符号投影长度。
Why:点积是 3D 数学的"万金油"——夹角余弦、光照、距离平方、相似度、矩阵乘法的几何底座;理解几何意义比记公式重要。
How:
代数定义(§2.11.1):
结果为标量。
几何定义(§2.11.2):Dot product as projection:a · b = b 在 a 方向上的 有符号投影长度 × ‖a‖。
几何等价形式:
其中 θ = 两向量夹角(0 ≤ θ ≤ π)。
关键性质:
-
交换律:\(\mathbf{a} \cdot \mathbf{b} = \mathbf{b} \cdot \mathbf{a}\)
-
结合律(与数乘):\((k\mathbf{a}) \cdot \mathbf{b} = k(\mathbf{a} \cdot \mathbf{b}) = \mathbf{a} \cdot (k\mathbf{b})\)
-
零向量点积:\(\mathbf{0} \cdot \mathbf{v} = 0\)
-
符号判定:
a · b > 0⇒ 同向(夹角 < 90°);= 0⇒ 正交;< 0⇒ 反向(夹角 > 90°)。
When:夹角余弦 cosθ = (a · b) / (‖a‖‖b‖);Lambert 光照 intensity = max(0, n · l);距离平方 ‖a − b‖² = ‖a‖² + ‖b‖² − 2(a · b);点积矩阵 C = AᵀB 的元素。
Example:a = [1, 3, 4]、b = [2, −5, 8] ⇒ a · b = 1×2 + 3×(−5) + 4×8 = 2 − 15 + 32 = 19。
2.6 叉积 (Cross Product)
What:叉积 a × b 仅在 3D 中定义;结果向量同时垂直于 a 与 b;大小 = ‖a‖‖b‖sinθ(平行四边形面积),方向由 手性 决定。
Why:叉积是构造平面 / 三角形 / 多边形法向量的唯一通用方法,也是判断"顺时针 vs 逆时针"的工具,在背面剔除、法线光照、三角形朝向中无处不在。
How:
代数定义(§2.12.1):
几何解释(§2.12.2):
-
大小:\(\|\mathbf{a} \times \mathbf{b}\| = \|\mathbf{a}\| \|\mathbf{b}\| \sin\theta\) =
a, b张成的平行四边形面积。 -
方向:垂直于
a, b所在平面;由手性 + 顺逆时针决定:-
左手系(本书):把
b尾接到a头,若为 顺时针 转弯则a × b朝向你。 -
右手系:若为 逆时针 转弯则
a × b朝向你。
-
关键性质:
-
反交换律:\(\mathbf{a} \times \mathbf{b} = -(\mathbf{b} \times \mathbf{a})\)
-
不结合:\((\mathbf{a} \times \mathbf{b}) \times \mathbf{c} \neq \mathbf{a} \times (\mathbf{b} \times \mathbf{c})\)
-
平行 / 零向量:\(\mathbf{a} \times \mathbf{b} = \mathbf{0}\) 当
a ∥ b或其一为零向量。 -
卡迪尔轴叉积(式 2-1 形式):
|
叉积的方向快速判定
沿"x → y → z → x"循环,"后一个叉前一个"得"第三个"(左手 / 右手都成立,只是 |
When:求三角形 / 多边形 / 平面法向量;背面剔除的方向判定;torque 公式 \(\boldsymbol{\tau} = \mathbf{r} \times \mathbf{F}\);生成与已知向量垂直的向量(取 up 与 forward 叉积得 right)。
Example:a = [1, 3, 4]、b = [2, −5, 8] ⇒ a × b = [(3)(8) − (4)(−5), (4)(2) − (1)(8), (1)(−5) − (3)(2)] = [44, 0, −11]。
三、关键图表
视觉图表
(x, y) 与向量 [x, y] 的关系
a, b 为边的平行四边形
非可视化条目
|
非可视化条目(表 / 算法)
|
核心公式对照表
|
核心公式对照表
|
四、思维导图
mindmap
root((第 2 章 向量))
向量定义
数学有序列表
几何有向线段
与位置无关
向量与点
向量相对位移
点绝对位置
类型区分
基本运算
取反翻向
数乘伸缩
加减平移拼接
大小与单位向量
magnitude
normalize
距离公式
点积
分量乘积之和
投影几何
交换律数乘结合
叉积
仅限3D
平行四边形面积
手性决定方向
反交换律
五、重点与易错点
-
向量 ≠ 点:数值可以相同,但语义不同——向量是位移、点是位置;C++ 中用
Vec3vsPoint3类型区分,否则会在Point + Point这种无意义运算上编译通过、运行崩溃。 -
点积几何意义优先于公式:把
a · b = ‖a‖‖b‖cosθ与 "投影"印在手背上,代码里只需调dot(a, b);3D 引擎 90% 的"两个向量对齐度"问题靠它解决。 -
点积符号 = 半空间判定:
>0同向、<0反向、=0正交;做光照时max(0, n·l)是 Lambert 模型的核心公式。 -
点积 vs 叉积的几何差异:点积把零向量视为"与所有向量垂直",叉积把零向量视为"与所有向量平行"——两者都是 运算结果 的解释,零向量本身既无方向也无垂直 / 平行可言。
-
叉积仅 3D:没有 4D 叉积;要在 4D 中构造法向量,必须借助"两向量叉积 + Gram-Schmidt"或"对偶四元数"。
-
叉积方向取决于手性:左手系顺时针朝你、右手系逆时针朝你;跨引擎复用叉积代码时第一件事是验证朝向(Unity 左手、Unreal / OpenGL 右手)。
-
叉积反交换律:
a × b = −(b × a);不要写b × a期望得到a × b。 -
向量大小必非负:
‖v‖ ≥ 0,‖v‖ = 0当且仅当v = 0;规范化前必须检查‖v‖ > 0避免除零崩溃。 -
数乘
k < 0同时翻向:方向取反 + 大小乘|k|,不要分开写成两步。 -
向量没有绝对位置:
v = [3, 1]既可画在原点也可画在(5, 5);相等判定只看大小与方向,与起点无关——这与"平移整个向量不改变身份"等价。 -
跨章衔接:第 3 章在笛卡尔坐标系 + 向量之上引入"多个坐标空间"与基向量;第 4 章把向量扩展为矩阵;第 5 章起把点积 / 叉积用于投影 / 法向量 / 旋转矩阵构造。