🧮 Cesium 矩阵系统详解:Matrix3 与 Matrix4 核心 API 全指南
矩阵是 Cesium 中三维变换的数学基础,Matrix3 (3×3 矩阵)和 Matrix4(4×4 矩阵)分别针对不同的变换场景设计。本文从定义、核心 API、参数、示例、场景、注意事项六个维度,全面解析 Cesium 矩阵系统的使用。
一、Matrix3 深度解析
1. 定义与核心特性
- 数学定义 :3×3 列主序矩阵,存储顺序为
[m00, m10, m20, m01, m11, m21, m02, m12, m22](列优先,与 WebGL 存储规范一致)。 - 核心用途 :
- 2D 仿射变换(平移、旋转、缩放);
- 3D 空间旋转(无平移分量,避免冗余计算);
- 法线变换(逆转置矩阵是法线变换的标准方式,Matrix3 更紧凑)。
- 优势:比 Matrix4 更轻量化,旋转/法线变换计算效率更高。
2. 常见 API 详解
(1)Matrix3.IDENTITY - 单位矩阵
-
参数:无(只读常量)
-
用途:作为变换的初始状态(无旋转、无缩放)。
-
示例 :
javascriptconst identityMatrix = Cesium.Matrix3.IDENTITY; console.log(identityMatrix); // 输出单位矩阵 -
使用场景:重置变换、初始化矩阵变量。
-
注意事项 :
- 该矩阵是只读的,不能直接修改,需修改时使用
Matrix3.clone()克隆后再操作。
- 该矩阵是只读的,不能直接修改,需修改时使用
(2)Matrix3.fromRotationX/Y/Z(angle) - 轴旋转矩阵
-
参数 :
angle(旋转角度,单位:弧度) -
用途:创建绕 X/Y/Z 轴旋转的纯旋转矩阵。
-
示例 :
javascript// 绕 Y 轴旋转 90 度(转弧度) const rotationMatrix = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90)); -
使用场景:3D 模型的单轴旋转、相机姿态调整。
-
注意事项 :
- 角度必须转成弧度,使用
Cesium.Math.toRadians(degrees)转换; - 旋转是相对于笛卡尔坐标系原点的,若需绕模型自身中心旋转,需先平移到原点再旋转。
- 角度必须转成弧度,使用
(3)Matrix3.fromQuaternion(quaternion, result) - 四元数转旋转矩阵
-
参数 :
quaternion:Cesium.Quaternion对象(归一化的四元数);result(可选):存储结果的 Matrix3,避免创建新对象。
-
用途:将四元数转换为旋转矩阵(四元数避免万向锁,适合平滑旋转)。
-
示例 :
javascript// 创建绕 (1,1,0) 轴旋转 45 度的四元数 const quaternion = Cesium.Quaternion.fromAxisAngle( Cesium.Cartesian3.normalize(Cesium.Cartesian3.fromElements(1,1,0), new Cesium.Cartesian3()), Cesium.Math.toRadians(45) ); // 转成 Matrix3 const rotationMatrix = Cesium.Matrix3.fromQuaternion(quaternion); -
使用场景:3D 模型的平滑旋转、相机姿态插值。
-
注意事项 :
- 输入的四元数必须归一化,否则旋转会产生缩放畸变。
(4)Matrix3.fromScale(scale, result) - 缩放矩阵
-
参数 :
scale:Cesium.Cartesian2(2D 缩放)或Cesium.Cartesian3(3D 缩放);result(可选):存储结果的 Matrix3。
-
用途:创建 2D/3D 缩放矩阵。
-
示例 :
javascript// 2D 缩放:X/Y 轴各放大 2 倍 const scaleMatrix = Cesium.Matrix3.fromScale(Cesium.Cartesian2.fromElements(2, 2)); -
使用场景:2D 图形缩放、3D 模型的非等比缩放。
-
注意事项 :
- 缩放因子为 0 会导致矩阵奇异(无法求逆),避免使用 0 值;
- 3D 缩放时 Z 分量不影响 2D 变换,可设为 1。
(5)Matrix3.multiply(left, right, result) - 矩阵乘法
-
参数 :
left:左矩阵;right:右矩阵;result(可选):存储乘积的 Matrix3。
-
用途:组合多个变换(如缩放 + 旋转)。
-
示例 :
javascript// 先缩放 2 倍,再绕 Y 轴旋转 90 度 const scaleMatrix = Cesium.Matrix3.fromScale(Cesium.Cartesian3.fromElements(2,2,2)); const rotationMatrix = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90)); // 乘法顺序:left * right → 先应用 right 的变换,再应用 left 的变换 const combinedMatrix = Cesium.Matrix3.multiply(rotationMatrix, scaleMatrix, new Cesium.Matrix3()); -
使用场景:组合多个基础变换(缩放→旋转→平移,Matrix3 仅支持缩放+旋转)。
-
注意事项 :
- 列主序矩阵的乘法顺序是右乘先执行 ,即
A*B表示先应用 B 的变换,再应用 A 的变换; - 矩阵乘法不满足交换律,顺序错误会导致变换结果不符合预期。
- 列主序矩阵的乘法顺序是右乘先执行 ,即
(6)Matrix3.inverse(matrix, result) - 逆矩阵
-
参数 :
matrix:输入矩阵;result(可选):存储逆矩阵的 Matrix3。
-
用途:还原变换(如将模型坐标转换为世界坐标的逆操作)。
-
示例 :
javascriptconst rotationMatrix = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90)); // 旋转矩阵是正交矩阵,逆矩阵等于转置矩阵 const inverseMatrix = Cesium.Matrix3.inverse(rotationMatrix, new Cesium.Matrix3()); -
使用场景:逆变换计算、法线变换(需逆转置矩阵)。
-
注意事项 :
- 奇异矩阵(行列式为 0,如缩放因子为 0 的矩阵)无法求逆,会返回
undefined; - 旋转矩阵是正交矩阵,其逆矩阵等于转置矩阵,可使用
Matrix3.transpose()替代inverse()提升性能。
- 奇异矩阵(行列式为 0,如缩放因子为 0 的矩阵)无法求逆,会返回
(7)Matrix3.transpose(matrix, result) - 转置矩阵
-
参数 :
matrix:输入矩阵;result(可选):存储转置矩阵的 Matrix3。
-
用途:法线变换(模型矩阵的逆转置矩阵用于法线向量的正确变换)、矩阵数据格式转换。
-
示例 :
javascriptconst modelMatrix3 = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90)); // 转置旋转矩阵(正交矩阵的逆等于转置) const transposedMatrix = Cesium.Matrix3.transpose(modelMatrix3, new Cesium.Matrix3()); -
使用场景:3D 模型的法线变换、WebGL 着色器矩阵传递。
-
注意事项 :
- 转置仅交换矩阵的行和列,不改变矩阵的行列式值。
二、Matrix4 深度解析
1. 定义与核心特性
- 数学定义 :4×4 列主序矩阵,存储顺序为
[m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33],通过齐次坐标(w 分量)支持平移变换。 - 核心用途 :
- 3D 全量仿射变换(平移、旋转、缩放的组合);
- 模型矩阵、视图矩阵、投影矩阵的核心表示;
- 坐标空间转换(如世界坐标→相机坐标→裁剪坐标)。
- 优势:用单个矩阵表示所有 3D 变换,便于组合、传递给 WebGL 着色器。
2. 常见 API 详解
(1)Matrix4.IDENTITY - 单位矩阵
-
参数:无(只读常量)
-
用途:初始化 3D 变换的初始状态(无平移、无旋转、无缩放)。
-
示例 :
javascriptconst modelMatrix = Cesium.Matrix4.clone(Cesium.Matrix4.IDENTITY); // 克隆后可修改 -
使用场景:3D 模型的初始变换、矩阵重置。
-
注意事项 :
- 内置
IDENTITY是只读的,需修改时必须先克隆。
- 内置
(2)Matrix4.fromTranslation(translation, result) - 平移矩阵
-
参数 :
translation:Cesium.Cartesian3(X/Y/Z 轴的平移量,单位:米);result(可选):存储结果的 Matrix4。
-
用途:创建仅包含平移的矩阵。
-
示例 :
javascript// 沿 X 轴平移 100 米,Y 轴平移 50 米 const translation = Cesium.Cartesian3.fromElements(100, 50, 0); const translateMatrix = Cesium.Matrix4.fromTranslation(translation); -
使用场景:3D 模型的位置调整、相机平移。
-
注意事项 :
- 平移量的单位是米(Cesium 笛卡尔坐标系的默认单位)。
(3)Matrix4.fromRotationX/Y/Z(angle, result) - 轴旋转矩阵
-
参数 :
angle:旋转角度(弧度);result(可选):存储结果的 Matrix4。
-
用途:创建绕 X/Y/Z 轴旋转的 4×4 矩阵(包含单位平移分量)。
-
示例 :
javascript// 绕 Z 轴旋转 45 度 const rotateMatrix = Cesium.Matrix4.fromRotationZ(Cesium.Math.toRadians(45)); -
使用场景:3D 模型的单轴旋转、相机姿态调整。
-
注意事项 :
- 旋转是相对于笛卡尔坐标系原点的,若需绕模型自身中心旋转,需先平移到原点再旋转。
(4)Matrix4.fromScale(scale, result) - 缩放矩阵
-
参数 :
scale:Cesium.Cartesian3(X/Y/Z 轴的缩放因子);result(可选):存储结果的 Matrix4。
-
用途:创建 3D 缩放矩阵。
-
示例 :
javascript// X/Y/Z 轴各放大 2 倍 const scaleMatrix = Cesium.Matrix4.fromScale(Cesium.Cartesian3.fromElements(2, 2, 2)); -
使用场景:3D 模型的等比/非等比缩放。
-
注意事项 :
- 非等比缩放会导致模型材质拉伸,需确保 3D 模型的 UV 坐标适配。
(5)Matrix4.fromRotationTranslation(rotation, translation, result) - 旋转+平移组合矩阵
-
参数 :
rotation:Cesium.Matrix3(旋转矩阵);translation:Cesium.Cartesian3(平移向量);result(可选):存储结果的 Matrix4。
-
用途:组合旋转和平移变换,是 3D 模型定位的核心 API。
-
示例 :
javascript// 绕 Y 轴旋转 90 度,再平移到 (100,50,0) const rotationMatrix = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90)); const translation = Cesium.Cartesian3.fromElements(100, 50, 0); const modelMatrix = Cesium.Matrix4.fromRotationTranslation(rotationMatrix, translation); -
使用场景:3D 模型的初始定位、3DTiles 模型的变换。
-
注意事项 :
- 变换顺序:先旋转,再平移(符合列主序乘法规则)。
(6)Matrix4.multiply(left, right, result) - 矩阵乘法
-
参数 :
left:左矩阵;right:右矩阵;result(可选):存储乘积的 Matrix4。
-
用途:组合多个 3D 变换(如缩放+旋转+平移)。
-
示例 :
javascript// 组合变换:缩放 2 倍 → 绕 Y 轴旋转 90 度 → 平移 (100,50,0) const scaleMatrix = Cesium.Matrix4.fromScale(Cesium.Cartesian3.fromElements(2,2,2)); const rotateMatrix = Cesium.Matrix4.fromRotationY(Cesium.Math.toRadians(90)); const translateMatrix = Cesium.Matrix4.fromTranslation(Cesium.Cartesian3.fromElements(100,50,0)); // 乘法顺序:translate * rotate * scale → 先缩放,再旋转,最后平移 const combinedMatrix = Cesium.Matrix4.multiply( translateMatrix, Cesium.Matrix4.multiply(rotateMatrix, scaleMatrix, new Cesium.Matrix4()), new Cesium.Matrix4() ); -
使用场景:复杂 3D 变换的组合、坐标空间转换链。
-
注意事项 :
- 列主序矩阵的乘法顺序是右乘先执行 ,即
A*B*C表示先应用 C,再应用 B,最后应用 A; - 避免频繁创建新矩阵,复用
result参数可提升性能。
- 列主序矩阵的乘法顺序是右乘先执行 ,即
(7)Matrix4.getTranslation(matrix, result) - 提取平移分量
-
参数 :
matrix:输入 Matrix4;result(可选):存储平移向量的Cesium.Cartesian3。
-
用途:从模型矩阵中提取当前的平移位置。
-
示例 :
javascriptconst modelMatrix = Cesium.Matrix4.fromTranslation(Cesium.Cartesian3.fromElements(100,50,0)); const translation = Cesium.Matrix4.getTranslation(modelMatrix, new Cesium.Cartesian3()); console.log(translation); // 输出 Cartesian3(100,50,0) -
使用场景:动态调整模型位置、获取模型的世界坐标。
-
注意事项 :
- 提取的平移向量是笛卡尔坐标系下的米单位。
(8)Matrix4.setTranslation(matrix, translation, result) - 设置平移分量
-
参数 :
matrix:输入 Matrix4;translation:新的平移向量;result(可选):存储修改后的 Matrix4。
-
用途:在不修改旋转/缩放的前提下,调整模型的位置。
-
示例 :
javascriptconst modelMatrix = Cesium.Matrix4.fromRotationY(Cesium.Math.toRadians(90)); // 设置平移到 (100,50,0),保留旋转分量 const updatedMatrix = Cesium.Matrix4.setTranslation(modelMatrix, Cesium.Cartesian3.fromElements(100,50,0), new Cesium.Matrix4()); -
使用场景:动态移动 3D 模型、相机位置调整。
-
注意事项 :
- 若不指定
result,会直接修改输入矩阵(引用类型),需注意副作用。
- 若不指定
(9)Matrix4.toArray(matrix, result) - 矩阵转列主序数组
-
参数 :
matrix:输入 Matrix4;result(可选):存储数组的Float64Array。
-
用途:将矩阵转换为 WebGL 着色器支持的列主序数组,传递给 uniform 变量。
-
示例 :
javascriptconst modelMatrix = Cesium.Matrix4.IDENTITY; const matrixArray = Cesium.Matrix4.toArray(modelMatrix); // 传递给 WebGL 着色器 gl.uniformMatrix4fv(modelMatrixLocation, false, matrixArray); -
使用场景:自定义 WebGL 着色器的矩阵传递、与外部渲染引擎交互。
-
注意事项 :
- WebGL 要求矩阵是列主序的,Cesium 的
toArray()直接输出符合要求的数组,无需转置。
- WebGL 要求矩阵是列主序的,Cesium 的
三、Matrix3 vs Matrix4 对比与适用场景
| 特性 | Matrix3 | Matrix4 |
|---|---|---|
| 维度 | 3×3 | 4×4 |
| 支持的变换 | 旋转、缩放、2D 平移 | 平移、旋转、缩放(全 3D 变换) |
| 存储效率 | 9 个浮点数(更轻量化) | 16 个浮点数(更灵活) |
| 核心场景 | 2D 变换、3D 旋转、法线变换 | 3D 全量变换、模型/视图/投影矩阵 |
| 性能 | 计算更快(适合高频变换) | 计算稍慢(但功能更全) |
四、通用注意事项
1. 列主序存储
Cesium 的矩阵均为列主序,与 WebGL 规范一致,避免了矩阵转置的性能开销。在手动创建矩阵时,需注意数组顺序为列优先:
javascript
// 手动创建平移矩阵:X 轴平移 100 米
const translateMatrixArray = [
1, 0, 0, 0, // 第一列
0, 1, 0, 0, // 第二列
0, 0, 1, 0, // 第三列
100, 0, 0, 1 // 第四列(平移分量)
];
const translateMatrix = Cesium.Matrix4.fromArray(translateMatrixArray);
2. 矩阵乘法顺序
列主序矩阵的乘法顺序是右乘先执行 ,即 A*B*C 表示变换顺序为 C → B → A,这与直觉上的"先做 C,再做 B,最后做 A"一致。
3. 性能优化
- 复用矩阵对象 :在循环或高频变换中,提前创建
result参数并复用,避免频繁创建新矩阵导致垃圾回收; - 优先使用内置 API:Cesium 的矩阵 API 经过 GPU 优化,比手动实现矩阵运算快 5-10 倍;
- 避免奇异矩阵:不要使用缩放因子为 0 的矩阵,否则无法求逆,会导致变换异常。
4. 坐标空间一致性
Cesium 中所有矩阵变换默认基于笛卡尔坐标系(米单位) ,与地理坐标系(经纬度)的转换需通过 Cesium.Transforms.eastNorthUpToFixedFrame() 等 API 实现。
通过掌握 Matrix3 和 Matrix4 的核心 API,你可以灵活实现 Cesium 中所有的三维变换需求,从简单的模型平移到复杂的坐标空间转换,为 WebGIS 三维可视化提供坚实的数学基础。