经纬志
首页 / three.js / 使用示例

轨迹线

北京、上海、广州、成都、西安连成一条闭合航线,亮点沿曲线前进并拖出尾迹。 曲线在球面之上生成,避免与球体穿插。

three.js 0.160.0 · 更新 2026-10-27
源码与运行效果
运行效果

说明

五个城市的经纬度先换算成球面点,半径取球半径的 1.06 倍,让航线浮在地表之上。 CatmullRomCurve3 把这些点串成平滑曲线,闭合参数设为 true; TubeGeometry 再沿曲线生成一段有粗细的管道。

亮点用 curve.getPointAt(t) 取位置,t 每秒增加约 0.11。 getPointAt 按弧长参数化,速度看起来均匀; 如果改用 getPoint,点会在曲线曲率变化处忽快忽慢。

参数取值作用
曲线类型centripetal抑制控制点过近导致的打结与过冲
管道分段360 / 8沿曲线 360 段,截面 8 边
管道半径0.012约为球半径的 0.75%
飞行速度0.11 圈/秒一圈约 9 秒,便于观察
尾迹长度40 个采样点环形缓冲,每帧前移一位
经纬网间距30°经线与纬线成对写入同一几何体

为什么用管道而不是线

WebGL 的线宽在多数平台上固定为 1 像素,做不出有体积感的航线。 TubeGeometry 把线变成实体,可以受光、可以有粗细、也能被遮挡, 视觉上更接近真实的三维航线。代价是顶点数增加,长航线要控制分段数。

尾迹的实现

尾迹不是把整条路径反复重绘,而是维护一个固定长度的点数组。 每帧把数组整体前移一位,把最新位置写进末尾,然后置 position.needsUpdate = true。长度固定,显存不增长, 这是动态线最省资源的写法。

初始化时把整段尾迹都填成起点,否则第一帧会看到一条从场景原点连过来的长线, 这是新几何体默认全零造成的常见现象。

换成真实航线

真实飞行轨迹应当使用大圆航线或实际的航路点,而不是把城市点直接连成样条。 大圆航线可以通过在两点间按球面插值采样生成,再交给 CatmullRomCurve3 或直接构建管道。 如果要贴合地形,还需要把高度设为航线高度加地形高程,并处理地球曲率。

先定球面,再谈曲线。控制点必须落在球面上,曲线才有地理含义。 随便在三维空间里取几个点连起来,画面可能好看,但那条线无法解释成航线。