第 1 章 笛卡尔坐标系 (Cartesian Coordinate Systems)
核心结论
-
3D 数学的根基是笛卡尔坐标系:通过原点、轴与有符号距离,把 3D 空间中"位置 / 距离 / 角度"的连续直观问题转化为代数计算。
-
1D→3D 是递进而非对称的:所有 2D 坐标系都可通过旋转对齐(无手性问题),但 3D 存在左手 / 右手两套不可旋转对齐的体系,这是后续矩阵 / 四元数 / 叉积符号差异的源头。
-
数值精度是工程权衡:C++ 中
short / int / float / double全是离散的,选型本质是精度权衡而非"离散 vs 连续"。书中"第一法则"——If it looks right, it is right.——把可视化验证置于数值严格性之上。 -
左手 vs 右手只差一个负号:把任意一个轴反向即可切换手性,对绝大多数公式影响仅在
z相关的符号上;但旋转"正方向"由对应手性的手指定则决定,混淆会导致旋转矩阵列序与叉积方向全错。 -
本书用左手系:+x=右、+y=上、+z=前(屏幕里则 +z=外);数学身份式在任何手性下都成立,但应用到旋转 / 投影时需明确差异。
-
数学预备集中于 §1.4:求和 / 区间 / 角度(度 vs 弧度)/ 三角函数与恒等式——后续章节默认读者掌握,不再展开。
|
本章主旨
本章是全书的"约定章"。它不引入新的 3D 工具,而是建立后续 12 章都要复用的词汇与坐标系惯例:从数系复习 → 2D 笛卡尔 → 3D 笛卡尔 → 左手 / 右手手性 → 全书采用的左手系约定 → 数学预备速览。第 2 章起的向量、矩阵、变换都是在这些约定之上展开。 |
一、核心概念
本章围绕 6 个核心概念展开:先从 1D 数系复习建立"连续 vs 离散"的工程直觉,再逐步上升到 2D / 3D 笛卡尔坐标系,然后用手性区分不可对齐的 3D 体系,最后约定本书惯例并补齐数学预备。
| 概念 | 定义 + 重要性 | 实现提示 |
|---|---|---|
数系与精度 |
自然数 → 整数 → 有理数 → 实数的层级;C++ 中 |
选择 |
2D 笛卡尔空间 |
由原点 + 两条互相垂直的轴构成,点的位置用 |
§1.2 完整定义;§1.2.3 给出"点到点的距离公式"前置;后续 2D 图形 / UV 坐标全部依赖此抽象。 |
3D 笛卡尔空间与坐标平面 |
增加第三条轴 z,三轴两两垂直。两轴确定一个坐标平面: |
§1.3.1 引入三平面;§1.3.2 把 2D 的"有符号距离"推广到 3D——点的 x 是到 yz 平面的有符号距离。 |
手性与坐标系方向 |
所有 3D 坐标系分两类:左手 / 右手。同手性可旋转对齐,异手性不可——只能通过反转一个轴切换。 |
§1.3.3 用手指给出"手性判定";表 1.1 列出三轴正方向的旋转映射(左手顺时针 / 右手逆时针)。后续矩阵列序、叉积方向、 |
本书的坐标惯例 |
左手系;+x=右、+y=上、+z=前;地理场景下 +x=东、+z=北。该惯例与 Unity 一致,与 OpenGL / DirectX 默认右手系需做 |
§1.3.4 全文约定;后续旋转公式默认按左手系推导,使用右手系 API 时要在投影矩阵里加 |
数学预备:求和 / 区间 / 弧度 / 三角 |
求和符号 |
§1.4 速览;公式表 1.2 给出常用角度的三角值;式 1-1 给出和差恒等式,后续向量点积 / 叉积推导会引用。 |
二、详细笔记
2.1 数系与精度 (Number Systems & Precision)
What:从自然数 → 整数 → 有理数 → 实数的层级,以及在计算机中以有限位宽近似实数带来的精度选择问题。
Why:3D 图形看似处理连续实数,但 GPU / CPU 只能存有限离散值。"看起来对"之所以成为第一法则,就是因为最后要把实数误差折算成"屏幕上看不出来"。
How:
C++ 数据类型的有效位宽(按当前 PC 约定):
| 类型 | 容量 |
|---|---|
典型用途 |
|
16 bit,约 65 536 值 |
不适合 VR;偶用于 packed vertex buffer |
|
32 bit,约 43 亿值 |
索引 / 像素坐标足够 |
|
32 bit,约 43 亿离散有理子集 |
顶点 / 法线 / 颜色;GPU 原生类型 |
|
64 bit,更高密度 |
第一法则(First Law of Computer Graphics):If it looks right, it is right.——在 3D 视觉场景下,肉眼不可见的浮点误差可被接受,远比追求数值的严格正确重要。
When:选 float vs double 时——若需要长时间累积(积分 / 物理链式变换)或精度敏感(碰撞检测、布尔运算),用 double;若每帧每顶点多次矩阵乘法且需要带宽,用 float。
Example:在 830 页长篇里,作者风趣地把"零"和"负数"的发明归功于"卖不存在的羊的快嘴商人"——但工程上 负数 与 零 是向量取反与矩阵奇异性判定的关键。
2.2 2D 笛卡尔空间 (2D Cartesian Space)
What:由原点(origin)与两条过原点的轴(x 轴 / y 轴)构成的平面框架;点的位置由 (x, y) 两个有符号距离唯一确定。
Why:所有 2D 渲染(屏幕像素、纹理 UV、地图、棋盘)都基于此抽象。把"现实中的位置"映射为"两个数"是图形编程的第一步。
How:
2D 笛卡尔坐标系的关键要素:
-
原点:坐标系的"中心",是两条轴的唯一交点。
-
两条互相垂直的轴:通常记 x 轴(水平)与 y 轴(垂直),正向由约定确定。
-
点的坐标:
P = (x, y),其中x是点到 y 轴的有符号距离,y是点到 x 轴的有符号距离。
|
轴向约定的多样性
约定不唯一:
在 2D 中,任意两个坐标系都可以通过旋转 / 镜像对齐——即"所有 2D 坐标系都等价"。这是 §1.3.3 进入 3D 时要颠覆的关键直觉。 |
When:用 2D 笛卡尔表示平面几何(屏幕像素、纹理采样、地图投影);用 极坐标(第 7 章)表示方向 / 距离分离的物理量(雷达、声音、旋转)。
Example:Cartesia 城用 "East 2nd Street / North 4th Street" 命名街道,对应 (x=2, y=4)。从 (2, 4) 到 (-2, -3) 的位移即 (-4, -7),向南 7 街 / 向西 4 街。
2.3 3D 笛卡尔空间与坐标平面 (3D Cartesian Space & Coordinate Planes)
What:在 2D 基础上增加第三条轴 z,三轴两两垂直;任意两轴确定一个 2D 坐标平面(xy / xz / yz),三平面两两垂直。
Why:从 2D 到 3D 不是"再加 50% 复杂度"——它引入了手性(§2.4),这一性质在 2D 中不存在。但 3D 任意坐标平面本身仍是合法的 2D 笛卡尔空间,可以独立分析(如地面 = xz 平面)。
How:
3D 笛卡尔坐标系的关键扩展:
-
第三条轴 z:与 x、y 都垂直,正方向由约定确定(左手 +z=前;右手 +z=外)。
-
三平面:
xy / xz / yz;每个平面包含两条轴,垂直于第三条。 -
3D 点定位:
(x, y, z),x是到 yz 平面的有符号距离(沿平行于 x 轴的直线测量),y是到 xz 平面的有符号距离,z是到 xy 平面的有符号距离。
|
3D 不再是 2D 的简单叠加
2D 中"所有坐标系等价"靠旋转即可对齐;3D 中存在两种 不可 通过旋转对齐的坐标系——左、右手系(§2.4)。这导致从 2D 直觉推导 3D 时,"看起来一样"的运算可能差一个负号。 |
When:3D 笛卡尔是第 2 章起所有内容的坐标系;坐标平面常用于把 3D 问题降维(如把角色动画投影到 xy 屏幕平面分析)。
Example:把 +x、+y、+z 分别赋为右、上、前时,"地面"就是 xz 平面(y=0),角色在地面上跑步等价于 2D xz 平面问题。
2.4 手性与坐标系方向 (Handedness)
What:3D 坐标系分左手系与右手系;同手性可旋转对齐,异手性只能通过翻转一个轴切换。正向旋转的方向(左手顺时针 / 右手逆时针)由对应手的手指定则(hand rule)给出。
Why:手性决定了叉积方向、旋转矩阵列序、欧拉角旋转符号、z 是否在投影公式中带负号——一旦混淆,所有旋转 / 朝向 / 法线方向的代码都会与可见结果相反。
How:
手性判定("手指定则"):
-
左手系:左手拇指=+x、食指=+y、中指=+z;观察轴正向时,正向旋转是 顺时针。
-
右手系:右手拇指=+x、食指=+y、中指=+z;正向旋转是 逆时针。
-
等价切换:反转任意一个轴的正方向(左 ↔ 右切换);交换两个轴等价于绕第三个轴旋转 180°,手性不变。
式 1-1 给出的手性差异——卡迪尔轴上的正向旋转映射:
When:写旋转矩阵 / 叉积 / 法线变换时,永远先问"当前手性是什么";跨引擎复用代码时(Unity 左手 ↔ OpenGL 右手),第一件事是在投影矩阵加 z 翻转。
Example:用右手系做 cross(forward, up),若得到 right,那么在左手系中要改成 cross(up, forward) 才能得到 right。
2.5 本书的坐标惯例 (Book Conventions)
What:本书采用左手系;+x=右、+y=上、+z=前;地理场景下 +x=东、+z=北。
Why:全书公式按此推导;复用本书代码到右手系(OpenGL / DirectX)时,需要把 z 翻转或调整矩阵列序。
How:
-
左手系:与 Unity 渲染管线默认一致;与 OpenGL / 传统线性代数默认的右手系相反。
-
轴映射:3D 屏幕视图下,+x=右、+y=上、+z=前(看向屏幕外);世界场景下,+x=东、+z=北,+y 仍为上。
-
不影响的部分:所有向量代数恒等式(点积对称性、叉积反交换律等)在任何手性下都成立;差异仅出现在"应用到具体旋转 / 投影"的最后一步。
|
3D 坐标系组合总数
2D 笛卡尔只有 8 种轴向组合(图 1.7),都可旋转对齐;3D 笛卡尔有 48 种组合(24 左手 + 24 右手),其中异手性 不可 对齐——这是把 3D 视为"50% 更复杂"是不够的根因。 |
When:阅读本书公式时,默认在左手系;如读者使用右手系引擎,在脑中加一次 z → -z 的镜像即可。
Example:把本书的视图矩阵直接喂给 OpenGL(右手指南),会出现"深度反转 + 朝向镜像"的复合错误,常见修正是在投影矩阵中乘一个 (1, 1, -1, 1) 的对角缩放。
2.6 数学预备:求和 / 区间 / 弧度 / 三角 (Math Refresher)
What:本节给出后续章节默认掌握的数学速览——求和记法、区间记法、弧度与角度互换、三角函数与恒等式。
Why:向量点积 / 叉积、矩阵乘法、傅里叶分析都基于这些记法。速览集中放在这里,后续章节直接使用。
How:
核心记法与换算:
-
求和记法:\(\sum_{i=1}^{n} a_i = a_1 + a_2 + \cdots + a_n\);连乘用
Π。 -
区间记法:
[a, b]闭区间(含端点),(a, b)开区间(不含端点),[a, b)半开;无穷端按开区间处理,如latexmath:[0, +\infty)。 -
弧度 ↔ 角度:\(1 \text{ rad} = (180/\pi)^\circ \approx 57.29578^\circ\),\(1^\circ = (\pi/180) \text{ rad} \approx 0.01745329 \text{ rad}\)。
-
三角函数(单位圆定义):\(\cos\theta = x,\ \sin\theta = y\)(射线端点
(x, y))。 -
毕达哥拉斯恒等式(式 1-1 之一):\(\sin^2\theta + \cos^2\theta = 1\),\(1 + \tan^2\theta = \sec^2\theta\),\(1 + \cot^2\theta = \csc^2\theta\)。
-
和差恒等式(式 1-1 主体):
When:所有后续章节直接使用以上记法;弧度在 C++ 中以 double 存储,三角函数 std::sin / std::cos / std::tan 接收弧度。
Example:把 30° 喂给 C++ std::sin 会得到 0.5 之外的奇怪值;正确做法是 std::sin(30 * M_PI / 180),对应表 1.2 第一行非零值。
三、关键图表
视觉图表
(x, y) 坐标的一般三角解释
非可视化条目
|
非可视化条目(表 / 算法)
|
核心公式对照表
|
核心公式对照表
|
四、思维导图
mindmap
root((第 1 章 笛卡尔坐标系))
数系与精度
自然数到实数
C++位宽选择
第一法则
2D 笛卡尔空间
原点与轴
点的有符号距离
8种2D方向皆等价
3D 笛卡尔空间
z轴与三平面
点的3D定位
2D直觉在3D失效
手性
左手系顺时针
右手系逆时针
翻转一轴切换手性
本书惯例
左手系
xyz前右上
地理x东z北
数学预备
求和与区间
弧度与角度
三角与毕达哥拉斯
五、重点与易错点
-
第一法则是工程取舍:3D 图形默认用
float,不要在不必要时升级到double;反之物理 / 累积运算上float漂移明显,需double。 -
2D 中所有坐标系都等价:任意两个 2D 笛卡尔坐标系可旋转 / 镜像对齐;屏幕坐标与数学坐标的差异仅是
y取向,不是"另一个坐标系"。 -
3D 手性不可旋转对齐:左手系与右手系是 不可 通过旋转互化的两类;只能在 3D 中通过反转一个轴切换。
-
手指定则给出旋转正方向:左手系正方向顺时针、右手系逆时针——表 1.1 列了三轴的具体映射,是后续叉积 / 旋转矩阵正确性的判断依据。
-
本书左手系约定:+x=右、+y=上、+z=前;移植到 OpenGL 右手系时第一件事是投影矩阵的
z翻转(乘(1, 1, -1, 1)对角矩阵或调整矩阵第三行符号)。 -
弧度 vs 角度:C++
std::sin / std::cos默认输入是弧度;把30°直接喂进去会得到~0.988这种看似合理但错误的值,正确做法是30 * M_PI / 180。 -
三角恒等式是后续推导工具:式 1-1 的和差展开在第 2 章向量点积 / 第 8 章欧拉角旋转推导中会被反复引用。
-
(x, y)的二义性:既可表示 2D 点,又可表示开区间 / 2D 向量——靠上下文区分;推荐在表达式中显式写P = (2, 4)(点)或v = (2, 4)(向量)。 -
3D 不是 2D 的 50% 增量:维度叠加带来的复杂度是非线性的,许多 2D 简单问题在 3D 中 未定义(如三角形顺逆时针在 3D 中依赖观察方向),这是后续章节反复回到 "降维到 2D" 思路的原因。
-
跨章衔接:第 2 章在 3D 笛卡尔之上引入向量(位置 / 位移 / 方向);第 7 章引入极坐标作为 2D / 3D 中"方向 + 长度"分离的另一选择;第 10 章把三角 / 弧度推广到 3D 几何(球坐标 / 弧长参数化)。