Files
planet/.sisyphus/plans/predicted-orbit.md
rayd1o 1784c057e5 feat(earth): add predicted orbit display for locked satellites
- Calculate orbital period from meanMotion
- Generate predicted orbit points with 10s sampling
- Show complete orbit line when satellite is locked
- Hide orbit when satellite is unlocked
- Color gradient: bright (current) to dark (end)
- Fix TLE epoch format issue with fallback circle orbit
- Add visibility change handler to clear trails on page hide
- Fix satellite count display after loading
- Merge predicted-orbit plan into single file
2026-03-23 05:41:44 +08:00

3.8 KiB
Raw Blame History

卫星预测轨道显示功能

TL;DR

锁定卫星时显示绕地球完整一圈的预测轨道轨迹,从当前位置向外渐变消失

Context

目标

点击锁定卫星 → 显示该卫星绕地球一周的完整预测轨道(而非当前的历史轨迹)

当前实现

  • TRAIL_LENGTH = 30 - 历史轨迹点数,每帧 push 当前位置
  • 显示最近30帧历史轨迹类似彗星尾巴

参考: SatelliteMap.space

  • 锁定时显示预测轨道
  • 颜色从当前位置向外渐变消失
  • 使用 satellite.js与本项目相同

实现状态

已完成

  • 计算卫星轨道周期(基于 meanMotion
  • 生成预测轨道点10秒采样间隔
  • 创建独立预测轨道渲染对象
  • 锁定卫星时显示预测轨道
  • 解除锁定时隐藏预测轨道
  • 颜色渐变:当前位置(亮) → 轨道终点(暗)
  • 页面隐藏时清除轨迹(防止切回时闪现)

🚧 进行中

  • 完整圆环轨道(部分卫星因 SGP4 计算问题使用 fallback 圆形轨道)
  • 每颗卫星只显示一条轨道

技术细节

轨道周期计算

function calculateOrbitalPeriod(meanMotion) {
  return 86400 / meanMotion;
}

预测轨道计算

function calculatePredictedOrbit(satellite, periodSeconds, sampleInterval = 10) {
  const points = [];
  const samples = Math.ceil(periodSeconds / sampleInterval);
  const now = new Date();
  
  // Full orbit: from now to now+period
  for (let i = 0; i <= samples; i++) {
    const time = new Date(now.getTime() + i * sampleInterval * 1000);
    const pos = computeSatellitePosition(satellite, time);
    if (pos) points.push(pos);
  }
  
  // Fallback: 如果真实位置计算点太少,使用圆形 fallback
  if (points.length < samples * 0.5) {
    points.length = 0;
    // ... 圆形轨道生成
  }
  
  return points;
}

渲染对象

let predictedOrbitLine = null;

export function showPredictedOrbit(satellite) {
  hidePredictedOrbit();
  // ... 计算并渲染轨道
}

export function hidePredictedOrbit() {
  if (predictedOrbitLine) {
    earthObjRef.remove(predictedOrbitLine);
    predictedOrbitLine.geometry.dispose();
    predictedOrbitLine.material.dispose();
    predictedOrbitLine = null;
  }
}

已知问题

1. TLE 格式问题

computeSatellitePosition 使用自行构建的 TLE 格式,对某些卫星返回 null。当前使用 fallback 圆形轨道作为补偿。

2. 多条轨道

部分情况下锁定时会显示多条轨道。需要确保 hidePredictedOrbit() 被正确调用。

性能考虑

点数估算

卫星类型 周期 10秒采样 点数
LEO 90分钟 540秒 ~54点
MEO 12小时 4320秒 ~432点
GEO 24小时 8640秒 ~864点

优化策略

  • 当前方案(~900点 GEO性能可接受
  • 如遇性能问题GEO 降低采样率到 30秒

验证方案

QA Scenarios

Scenario: 锁定 Starlink 卫星显示预测轨道

  1. 打开浏览器,进入 Earth 页面
  2. 显示卫星(点击按钮)
  3. 点击一颗 Starlink 卫星(低轨道 LEO
  4. 验证:出现黄色预测轨道线,从卫星向外绕行
  5. 验证:颜色从亮黄渐变到暗蓝
  6. 验证:轨道完整闭环

Scenario: 锁定 GEO 卫星显示预测轨道

  1. 筛选一颗 GEO 卫星(倾斜角 0-10° 或高轨道)
  2. 点击锁定
  3. 验证:显示完整 24 小时轨道(或 fallback 圆形轨道)
  4. 验证:点数合理(~864点或 fallback

Scenario: 解除锁定隐藏预测轨道

  1. 锁定一颗卫星,显示预测轨道
  2. 点击地球空白处解除锁定
  3. 验证:预测轨道消失

Scenario: 切换页面后轨迹不闪现

  1. 锁定一颗卫星
  2. 切换到其他标签页
  3. 等待几秒
  4. 切回页面
  5. 验证:轨迹不突然闪现累积