深色模式
矩阵、基与坐标变换
坐标系(coordinate system)像一份编码约定:原点在哪里,三根轴朝哪里,单位是什么。同一个物理箭头,在不同坐标系中会有不同的数字。矩阵(matrix)可以把这类编码转换写成可组合的函数。
一列就是一根新轴
基(basis)是一组用来表达所有向量的独立方向。标准基为 (1,0,0)、(0,1,0)、(0,0,1)。如果局部 X、Y、Z 轴在世界坐标中分别是 e₁、e₂、e₃,将它们作为矩阵的三列:
这就是矩阵乘向量的直觉:按三个坐标值缩放三根基向量,再相加。**坐标写成列向量(column vector)**是本书约定;换用行向量时,乘法的写法也要相应改变。
| 符号 / 英文 | 含义 | 单位或条件 |
|---|---|---|
| R / rotation matrix | 旋转矩阵 | 无量纲;列向量正交、为单位长度,且保持右手方向 |
| t / translation | 局部原点的世界位置 | m |
| p / position | 点的位置 | m |
| Rᵀ / transpose | 行列交换后的矩阵 | 纯旋转时等于 R⁻¹ |
| R⁻¹ / inverse | 撤销该变换的逆矩阵 | 矩阵可逆时存在 |
正交矩阵(orthogonal matrix)的列两两垂直且长度为 1;它既可以表示旋转,也可能包含镜像。纯旋转还必须保持坐标系的左右手方向,用行列式(determinant)表示就是 det(R)=+1。镜像的行列式为 −1;曲线网格一节会解释这个数的几何意义。
手算:旋转 90° 再平移
在平面内绕 Z 轴逆时针旋转 90°,局部 X 轴变为世界 Y 轴,局部 Y 轴变为世界负 X 轴:
若先平移再旋转,结果是 R × (12,21,0) = (-21,12,0)。矩阵乘法通常不满足交换律(commutativity)。对列向量而言,T R p 先执行最右边的 R,再执行 T;可以把它读作函数调用 T(R(p))。
ts
type Vec3 = readonly [number, number, number]
const rotate90 = ([x, y, z]: Vec3): Vec3 => [-y, x, z]
const toWorldPoint = (p: Vec3): Vec3 => {
const r = rotate90(p)
return [r[0] + 10, r[1] + 20, r[2]]
}
toWorldPoint([2, 1, 0]) // [9,22,0]
rotate90([2, 1, 0]) // 方向只旋转,不加原点位置东—北—天参考系(East-North-Up frame,ENU)使用当前位置的东、北、椭球法线作为三根基。Cesium 的 eastNorthUpToFixedFrame 负责构造这项变换。数组的列主序存储(column-major storage)与列向量乘法约定有关联,但不是同一个概念;不要仅凭内存排列推断乘法顺序。
自检:怎样变回局部坐标
已知 p_world = R p_local + t,R 是纯旋转矩阵,能否写成 p_local = Rᵀ p_world − t?
答案与理由
一般不能。先减去平移,再撤销旋转:p_local = Rᵀ(p_world − t)。本例先用 (9,22,0)−(10,20,0)=(-1,2,0),再顺时针转 90°,得到 (2,1,0)。有缩放或错切时,不能直接用转置代替逆矩阵。