第 9 章 几何图元 (Geometric Primitives)

      +

      核心结论

      • 几何图元的 4 种表示技术:隐式(满足方程的点集)、参数化(用 t 参数描述)、"特定类型"(球、平面等专用)、"显式"(列出顶点)——每种各有优劣,按场景选用。

      • 线与射线:参数化 P(t) = P₀ + t d;射线 t ≥ 0;线可双向延伸;2D 隐式 ax + by + c = 0 与参数化互转。

      • 球与圆:中心 c + 半径 r;隐式 |P − c|² = r²;点积形式 P − c) · (P − c = r²;球与光线相交用 §10.4 二次方程。

      • 包围盒 (AABB):轴对齐长方体,min/max 两个点描述;碰撞检测快(O(1));变换后需重算(§9.4.4)。

      • 平面:隐式 n · x = d(n 是单位法向量、d 是原点到平面距离);点-平面距离 |n · p − d|;平面-平面 / 平面-射线 / 平面-三角形相交。

      • 三角形:3 顶点 + 法向量;面积 = |e₁ × e₂| / 2;重心坐标 α + β + γ = 1 是三角形内点的代数描述。

      • 多边形:分为简单 / 复杂、凸 / 凹;3D 引擎几乎只用三角形;任意多边形可 三角剖分

      本章主旨

      本章把第 2 章的"点 / 向量"具象化为"线 / 面 / 体"等几何图元。每种图元介绍表示方法、关键运算(距离 / 相交 / 法向量)、3D 引擎中的常见应用。后续章节会用到这些图元:第 10 章的视图体(视锥体)依赖 AABB,第 11 章的碰撞检测依赖球 / 平面 / 三角形,第 13 章的曲线依赖参数化。

      一、核心概念

      本章围绕 7 个核心概念展开:从 4 种表示技术出发,依次介绍线、球、AABB、平面、三角形、多边形的几何表示与关键运算。

      概念 定义 + 重要性 实现提示

      4 种表示技术

      隐式(满足方程的点集)、参数化(用 t 描述)、特定类型(球 / 平面等)、显式(顶点列表);每种适合不同任务。

      §9.1;判别测试用隐式(点是否在内);生成图元用参数化(t 取值);碰撞用特定类型;渲染用显式。

      线与射线

      参数化 P(t) = P₀ + t d(t ∈ ℝ 为线,t ≥ 0 为射线);2D 隐式 ax + by + c = 0(a² + b² = 1)。

      §9.2;线-线 / 线-平面 / 线-三角形相交是图形基础运算。

      中心 c + 半径 r;隐式 `

      P −

      ² = r²` 或点积形式 P − c) · (P − c = r²

      §9.3;球-球 / 球-光线 / 球-AABB 相交是物理引擎基础。

      AABB (轴对齐包围盒)

      由 min / max 两点描述;与坐标轴对齐;碰撞检测 O(1);变换后需重算(旋转后变 OBB)。

      §9.4;八叉树 / BVH 加速碰撞用 AABB 做粗筛。

      平面

      隐式 n · x = d(n 是单位法向量、d 是原点到平面有符号距离);三种定义:法向量 + 距离、三点法、最佳拟合。

      §9.5;点-平面距离 `

      n · p −

      `;平面-三角形相交;视锥剔除。

      三角形

      3 顶点 + 边向量 e₁, e₂;面积 `

      e₁ × e₂

      / 2`;重心坐标 (α, β, γ) 满足 α + β + γ = 1

      §9.6;3D 引擎几何基础;重心坐标用于纹理映射、shader 插值。

      多边形

      简单(无自交)/ 复杂;凸(任意两点连线在多边形内)/ 凹;3D 引擎几乎只用三角形(任意多边形可 三角剖分)。

      §9.7;多边形法向量 = 各三角形法向量之和 / 面积 加权平均。

      二、详细笔记

      2.1 4 种表示技术 (Representation Techniques)

      What:4 种描述几何图元的方法——隐式、参数化、特定类型、显式。

      Why:每种方法在不同任务上各有优势;选择合适的表示可大幅简化代码。

      How

      表示 形式

      优势场景

      隐式 (implicit)

      满足 f(P) = 0 的所有 P 构成图元

      判别测试(点是否在图元上)、求交、计算距离

      参数化 (parametric)

      P(t) = …​,t 是参数

      生成图元(取 t 值遍历)、光栅化

      特定类型 (specific type)

      球 / 平面 / 圆 等专用数据结构

      直接的几何运算(半径 / 法向量)

      显式 (explicit)

      顶点列表

      表示转换的工程实例
      • 球:隐式 |P - c|² = r²(判测试)、参数化 P(u, v) = c + r · (cos u sin v, sin u sin v, cos v)(生成网格)。

      • 平面:隐式 n · x = d(点-平面距离)、三点法(拟合)、"特定类型"(法向量 + 距离)、三角形列表(渲染)。

      When:每设计一个新图元时考虑 4 种表示各自的成本;通常同时保留 2-3 种。

      Example:3D 引擎中的"三角形"既存储为顶点(显式)、又存储为法向量(特定类型)、纹理坐标用重心坐标计算(参数化)。

      2.2 线与射线 (Lines and Rays)

      What:参数化 P(t) = P₀ + t d;线 t ∈ ℝ、射线 t ≥ 0、P₀ 是起点、d 是方向向量。

      Why:光追、相机射线、碰撞检测、3D 拾取(鼠标点 → 3D 射线)的基础。

      How

      参数化形式(§9.2):

      \[\mathbf{P}(t) = \mathbf{P}_0 + t \mathbf{d}\]

      2D 隐式形式(法线式):

      \[\mathbf{n} \cdot \mathbf{P} = d\]

      其中 n = (a, b) 是单位法向量,d 是原点到线距离。

      "射线"vs"线"
      • 线(line):t ∈ ℝ,双向无限。

      • 射线(ray):t ≥ 0,从起点出发单向。

      • 线段(segment):t ∈ [t₀, t₁],有限长。 图形 API 多用射线(相机拾取、光线追踪),物理引擎多用线段(碰撞边界)。

      When:相机射线(拾取 / 光追);碰撞检测(线 vs 三角形 / 球 / AABB);曲线参数化(第 13 章)。

      ExampleP(t) = (1, 2, 3) + t · (0, 0, 1) = z 轴上从 (1, 2, 3) 出发的射线。

      2.3 球与圆 (Spheres & Circles)

      What:中心 c + 半径 r;隐式 |P − c|² = r²;点积形式 P − c) · (P − c = r²

      Why:3D 物理碰撞检测的最简单图元;点积形式避免了 sqrt 调用(平方距离比较)。

      How

      隐式(§9.3):

      \[(\mathbf{P} - \mathbf{c}) \cdot (\mathbf{P} - \mathbf{c}) = r^2\]

      球-球碰撞(圆心距离 ≤ 半径之和);球-AABB(§9.4);球-光线(§10.4 二次方程)。

      参数化(生成球面网格):

      \[\mathbf{P}(u, v) = \mathbf{c} + r (\cos u \sin v,\ \sin u \sin v,\ \cos v),\quad u \in [0, 2\pi],\ v \in [0, \pi]\]
      点积形式的工程优势

      判别"点是否在球内"用 P - c) · (P - c ≤ r²|P - c| ≤ r 少一次 sqrt;批量判定时显著加速。

      When:物理引擎的"球体碰撞器";包围球(粗筛);3D 拾取的"吸附"判定。

      Example:点 (0, 0, 5) 是否在中心 (0, 0, 0)、半径 3 的球内?(0²+0²+5²) = 25 > 9,不在。

      2.4 包围盒 AABB (Axis-Aligned Bounding Box)

      What:与坐标轴对齐的长方体;由 min / max 两点描述(每轴独立的最小最大值)。

      Why:碰撞检测 O(1) 判定;BVH / 八叉树加速结构的基础;内存友好(6 个数)。

      How

      AABB 表示(§9.4.1):

      \[\mathbf{p}_{\min} = (x_{\min}, y_{\min}, z_{\min}),\quad \mathbf{p}_{\max} = (x_{\max}, y_{\max}, z_{\max}) \end{bmatrix}\]

      或用中心 + 半边长 (c, e)c = (pmin + pmax) / 2e = (pmax - pmin) / 2

      AABB-AABB 相交(O(1)):

      \[\text{intersect} \iff \forall i \in \{x, y, z\}: p_{\max}^{A,i} \ge p_{\min}^{B,i} \land p_{\max}^{B,i} \ge p_{\min}^{A,i}\]

      变换后重算(§9.4.4):旋转后 AABB 变 OBB(Oriented BB);若仍用 AABB 需重算 pmin/pmax(取旋转后所有顶点 min/max)。

      AABB vs OBB vs 包围球
      • AABB:内存小(6 数)、碰撞快(O(1));缺点:旋转后不再紧贴物体。

      • OBB(Oriented BB):紧贴旋转物体;内存 15 数(中心 + 3 正交基向量 + 3 半边长);碰撞较慢。

      • 包围球:内存 4 数(中心 + 半径);旋转不变;缺点:长物体浪费空间。 通常层级结构:AABB 粗筛 → OBB / 三角形细判。

      When:BVH / 八叉树节点;物理引擎粗筛碰撞;UI 元素边界;2D 游戏的 sprite 边界。

      Example:物体占据 [0, 0, 0] ~ [2, 3, 1],AABB = { pmin = (0,0,0), pmax = (2,3,1) }

      2.5 平面 (Planes)

      What:隐式 n · x = d(n 单位法向量、d 原点到平面有符号距离);3 种定义:法向量 + 距离、三点法、最佳拟合。

      Why:碰撞 / 物理 / 视锥剔除 / 镜像反射面都用平面;3D 引擎必备图元。

      How

      隐式形式(§9.5.1):

      \[\mathbf{n} \cdot \mathbf{x} = d \end{bmatrix}\]

      点-平面距离:

      \[\text{distance} = \mathbf{n} \cdot \mathbf{p} - d \end{bmatrix}\]

      正数:点在法向量一侧;负数:另一侧。

      三点定义平面(§9.5.2):n = (B − A) × (C − A)d = n · A(注意单位化 n)。

      "法向量 + d"的便利
      • 镜像反射:P' = P - 2(n · P - d) n

      • 投影到平面:P_proj = P - (n · P - d) n

      • 平面-平面交线 = 两平面法向量叉积方向上的直线。

      When:物理碰撞平面(地面、墙);视锥体 6 个面;水面 / 镜像面;CSG 几何运算。

      Examplen = (0, 1, 0)d = 0 即 xz 平面(地面);点 (0, 5, 0) 在法向量一侧距离 5。

      2.6 三角形 (Triangles)

      What:3 顶点 + 边向量 e₁, e₂;面积 |e₁ × e₂| / 2;重心坐标 (α, β, γ) 满足 α + β + γ = 1

      Why:3D 引擎几何基础(GPU 渲染、碰撞、纹理映射);硬件优化(光栅化针对三角形)。

      How

      边向量(§9.6):

      \[\mathbf{e}_1 = P_1 - P_0,\quad \mathbf{e}_2 = P_2 - P_0 \end{bmatrix}\]

      面积(§9.6.2):

      \[A = \frac{1}{2} \|\mathbf{e}_1 \times \mathbf{e}_2\| \end{bmatrix}\]

      重心坐标(§9.6.3):点 P 在三角形内 ⇔ P = α P₀ + β P₁ + γ P₂α + β + γ = 1α, β, γ ≥ 0

      法向量:

      \[\mathbf{n} = \frac{\mathbf{e}_1 \times \mathbf{e}_2}{\|\mathbf{e}_1 \times \mathbf{e}_2\|} \end{bmatrix}\]
      重心坐标的工程用途
      • 纹理映射:顶点 UV 用重心坐标插值(仿射 / 透视校正)。

      • shader 插值:所有顶点属性(法向量、颜色)默认用重心坐标插值。

      • 碰撞检测:点 vs 三角形 / 线段 vs 三角形都基于重心坐标。

      When:3D 模型网格;GPU 渲染基本单元;物理碰撞;CSG;纹理映射。

      Example:三角形顶点 (0,0,0)(1,0,0)(0,1,0)。重心 (0.5, 0.3, 0.2) 对应点 (0.3, 0.2, 0)(在三角形内)。

      2.7 多边形 (Polygons)

      What:3+ 顶点的封闭图元;分简单(无自交)/ 复杂;凸(任意两点连线在多边形内)/ 凹。

      Why:实际模型数据多边形数远超 3;3D 引擎几乎只用三角形(任意多边形可三角剖分)。

      How

      分类(§9.7.1-§9.7.2):

      • 简单 vs 复杂:边界是否自交。

      • 凸 vs 凹:任意两点连线是否在多边形内。

      • 三角形化 / 扇形化(§9.7.3):凹多边形必须先分解为凸子多边形再三角化。

      法向量(任意多边形):

      \[\mathbf{n}_{\text{polygon}} = \sum_i A_i \mathbf{n}_i \end{bmatrix}\]

      其中 A_i 是第 i 个三角形的面积、n_i 是其单位法向量。

      多边形 vs 三角网格
      • 3D 引擎 几乎不用 通用多边形——三角网格性能稳定、GPU 优化好。

      • 数据导入阶段(FBX / glTF)把所有多边形三角剖分。

      • 物理引擎(碰撞器)可用凸多边形;但渲染必须三角化。

      When:模型导入;碰撞器构造(凸 vs 凹);CSG 运算(Boolean 操作)。

      Example:六边形(凸六边形)= 6 顶点;可分解为 4 个三角形(fan from first vertex);3D 引擎只渲染这 4 个三角形。

      三、关键图表

      视觉图表

      图 9-1
      Figure 1. 图 9-1:4 种表示技术示意
      图 9-2
      Figure 2. 图 9-2:射线参数化
      图 9-3
      Figure 3. 图 9-3:球的几何
      图 9-4
      Figure 4. 图 9-4:AABB 与旋转后变 OBB
      图 9-5
      Figure 5. 图 9-5:平面(法向量 + d)
      图 9-6
      Figure 6. 图 9-6:三角形重心坐标
      图 9-7
      Figure 7. 图 9-7:凸 vs 凹多边形

      非可视化条目

      非可视化条目(表 / 算法)
      编号 内容摘要

      表 9.1

      4 种表示技术对比(隐式 / 参数化 / 特定类型 / 显式)。

      式 9-1 至 9-12

      几何图元的核心公式:射线参数化、平面隐式、球面积、AABB 相交、重心坐标。

      列表 9.1-9.x

      C 代码:AABB 计算、平面定义、三角形面积、重心坐标求解。

      表 9.2

      "最佳拟合"平面算法(最小二乘法,3+ 点)。

      核心公式对照表

      核心公式对照表
      图元 核心公式

      射线参数化

      \(\mathbf{P}(t) = \mathbf{P}_0 + t \mathbf{d},\ t \ge 0\)

      球隐式

      \((\mathbf{P} - \mathbf{c}) \cdot (\mathbf{P} - \mathbf{c}) = r^2\)

      平面隐式

      \(\mathbf{n} \cdot \mathbf{x} = d\)

      AABB 相交

      \(\forall i: p_{\max}^{A,i} \ge p_{\min}^{B,i} \land p_{\max}^{B,i} \ge p_{\min}^{A,i}\)

      三角形面积

      \(A = \frac{1}{2} |\mathbf{e}_1 \times \mathbf{e}_2|\)

      重心坐标

      \(\mathbf{P} = \alpha \mathbf{P}_0 + \beta \mathbf{P}_1 + \gamma \mathbf{P}_2,\ \alpha + \beta + \gamma = 1\)

      三角形法向量

      \(\mathbf{n} = \frac{\mathbf{e}_1 \times \mathbf{e}_2}{|\mathbf{e}_1 \times \mathbf{e}_2|}\)

      四、思维导图

      mindmap
        root((第 9 章 几何图元))
          4种表示
            隐式方程
            参数化
            特定类型
            显式顶点
          线与射线
            参数化
            隐式法线式
            拾取与光追
          球
            中心加半径
            点积形式
            物理碰撞
          AABB
            minmax两点
            O1碰撞
            变换后重算
          平面
            法向量加d
            点距离
            镜像反射
          三角形
            3顶点
            重心坐标
            面积
          多边形
            凸凹分类
            三角剖分
            法向量加权

      五、重点与易错点

      1. 4 种表示各有用途:判别测试用隐式、生成用参数化、碰撞用特定类型、渲染用显式;不要把一种表示硬套到所有场景。

      2. 射线 vs 线 vs 线段:射线 t ≥ 0、线 t ∈ ℝ、线段 t ∈ [t₀, t₁];3D 拾取用射线,光线追踪常用射线,碰撞边界用线段。

      3. 球的点积形式省一次 sqrt:批量判定"点是否在球内"用 P-c)·(P-c ≤ r²|P-c| ≤ r 快。

      4. AABB 旋转后变 OBB:若仍想用 AABB 必须重算 pmin/pmax(用旋转后所有顶点的 min/max);BVH 中节点常用 AABB,但对象本身常用 OBB / 包围球。

      5. 平面法向量必须单位化:否则点-平面距离 n · p - d 不准;三点法构造平面后立即 n /= |n|

      6. 三角形的"顶点顺序"决定正面:逆时针(行向量约定下左手系)通常为正面;背面剔除 / 透明排序据此判断。

      7. 重心坐标必须 α + β + γ = 1:三角形内点 ⇒ 三者均 ≥ 0;shader 用重心坐标插值所有顶点属性。

      8. 多边形法向量需面积加权:凹多边形简单平均法向量会抵消;必须用 Σ Aᵢ nᵢ

      9. *凹多边形必须先分解为凸子多边形*再三角化,否则扇形展开会出错。

      10. 跨章衔接:第 10 章用 AABB 构造视锥体、用平面构造视锥体 6 个面;第 11 章物理引擎用球 / AABB / 平面 / 三角形做碰撞;第 13 章曲线参数化是射线参数化的扩展。