Cartesian3
地心直角坐标系下的一个三维点,单位米。Cesium 里所有几何计算、位置赋值、 相机定位最终用的都是它。
x、y、z 是从地心出发的三个方向的分量(ECEF),
不是经纬度。直接 new Cesium.Cartesian3(116.39, 39.90, 0)
得到的是地心附近一个点,不是北京。
从经纬度构造
实际业务里几乎只用下面这几个工厂方法,构造完就丢弃 new。
| 方法 | 输入 | 用途 |
|---|---|---|
fromDegrees(lng, lat, height) | 度、度、米 | 单个点,高度可省略,默认 0 |
fromDegreesArray(array) | [lng, lat, lng, lat, ...] | 折线、多边形的顶点 |
fromDegreesArrayHeights(array) | [lng, lat, h, ...] | 带高度的三维折线 |
fromRadians(lng, lat, height) | 弧度 | 输入本身是弧度时避免来回转换 |
fromCartesian(cartographic) | Cartographic | 与 Cartographic.fromCartesian 互为逆运算 |
// 单个点:北京,海拔 0 米
var beijing = Cesium.Cartesian3.fromDegrees(116.391263, 39.907359);
// 一条折线的顶点,展平传入
var path = Cesium.Cartesian3.fromDegreesArray([
116.39, 39.90,
121.47, 31.23,
113.26, 23.13
]);
// 带高度:每个点 500 米
var path3d = Cesium.Cartesian3.fromDegreesArrayHeights([
116.39, 39.90, 500,
121.47, 31.23, 500
]);
矢量运算
| 方法 | 说明 |
|---|---|
distance(a, b) | 两点直线距离(弦长),不是地表距离 |
add / subtract | 向量加减,结果仍是坐标分量 |
multiplyByScalar / divideByScalar | 缩放 |
magnitude | 向量长度,即到地心的距离 |
normalize | 单位向量,常用来取「当地天顶方向」 |
dot / cross | 点积与叉积 |
midpoint | 两点的空间中点,会落在地球内部 |
lerp | 按比例插值两个坐标 |
equals / equalsEpsilon | 精确比较与带容差比较 |
distance 是弦长。北京到上海算出来约 1067 公里,沿地表的大圆距离约 1068 公里。
城市尺度看不出差别,跨洲际或做里程统计时必须换用
Cesium.EllipsoidGeodesic 取 surfaceDistance。
复用 result 参数
几乎所有方法都有可选的最后一个参数 result,用来把结果写进已有对象,
避免每帧分配新对象:
var scratch = new Cesium.Cartesian3();
// 每帧都会调用的代码里,这样写
Cesium.Cartesian3.add(a, b, scratch);
// 不加 result 是这种写法,每帧产生一个垃圾对象
var sum = Cesium.Cartesian3.add(a, b);
动画循环里每帧创建几十个 Cartesian3,会让 GC 频繁触发,表现为周期性卡顿。 Cesium 内部源码全用 scratch 变量,业务代码里热路径也应该照做。
转换成经纬度
var carto = Cesium.Cartographic.fromCartesian(beijing);
console.log(
Cesium.Math.toDegrees(carto.longitude), // 116.391263
Cesium.Math.toDegrees(carto.latitude), // 39.907359
carto.height // 0
);
拾取、模型坐标、CZML 位置拿到的都是 Cartesian3,要展示给用户前必须走一次这个转换。
转换结果里的经纬度是弧度,输出前记得 toDegrees。
四个常见错误
1. 把经纬度直接当分量
new Cesium.Cartesian3(116.39, 39.90, 0) 不会报错,只是把点扔到了地心附近,
相机飞过去看到一片黑。看到坐标值只有两位数三位数,基本可以确定是这个错。
2. 角度单位混用
fromDegrees 收度,fromRadians 收弧度,
Cartographic 的属性一律是弧度。混用的结果是位置偏到几百公里外。
3. 用 === 比较两个坐标
浮点结果不会完全相等,即使两次输入相同。判断是否同一点用
equalsEpsilon(a, b, 0.0001),或者先转成字符串保留固定小数位。
4. 修改已有坐标对象
Cartesian3 的属性可写,但把同一个对象同时赋给两个实体后改它的值,
两个实体的位置会一起变,因为引用是同一个。需要独立位置时用
Cartesian3.clone()。
经纬志(2026)。《Cartesian3》。https://www.jingweizhi.com/cesium/api/cartesian3.html(访问日期 2026-11-03)。