经纬志
首页 / Cesium / API 文档

Cartesian3

先看结论

地心直角坐标系下的一个三维点,单位米。Cesium 里所有几何计算、位置赋值、 相机定位最终用的都是它。

最后验证 2026-11-03 · CesiumJS 1.121 · 更新 2026-10-27 · 引用本文
new Cesium.Cartesian3(x, y, z)

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)。