轨迹线
北京、上海、广州、成都、西安连成一条闭合航线,亮点沿曲线前进并拖出尾迹。 曲线在球面之上生成,避免与球体穿插。
说明
五个城市的经纬度先换算成球面点,半径取球半径的 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 或直接构建管道。
如果要贴合地形,还需要把高度设为航线高度加地形高程,并处理地球曲率。
先定球面,再谈曲线。控制点必须落在球面上,曲线才有地理含义。 随便在三维空间里取几个点连起来,画面可能好看,但那条线无法解释成航线。