6.2 KiB
6.2 KiB
Cosmo - 深空探测器可视化系统
项目概述
基于 NASA JPL Horizons 数据的深空探测器 3D 可视化系统,展示旅行者号、火星探测器等深空探测器在太阳系中的实时位置和历史轨迹。
技术栈
后端
- 框架: Python 3.11+ with FastAPI
- 核心库:
fastapi- Web 框架astroquery- NASA JPL Horizons 数据查询astropy- 天文计算和时间处理uvicorn- ASGI 服务器pydantic- 数据验证python-dotenv- 环境变量管理
前端
- 框架: React 18 with TypeScript
- 构建工具: Vite
- 3D 渲染:
three- 核心 3D 引擎@react-three/fiber- React Three.js 集成@react-three/drei- Three.js 辅助组件
- UI 库:
tailwindcss- 样式框架lucide-react- 图标库
- 状态管理: React Hooks (useState, useContext)
- HTTP 客户端:
axios
核心功能
1. 数据获取
- 从 NASA JPL Horizons 获取探测器和行星的日心坐标 (x, y, z)
- 支持时间序列查询(用户指定起止时间)
- 数据缓存策略:每3天更新一次
- 单位:AU (天文单位)
2. 支持的天体
探测器
| 名称 | ID | 备注 |
|---|---|---|
| Voyager 1 | -31 | 最远的人造物体 |
| Voyager 2 | -32 | 访问过天王星海王星 |
| New Horizons | -98 | 冥王星探测器 |
| Parker Solar Probe | -96 | 最接近太阳 |
| Juno | -61 | 木星探测器 |
| Cassini | -82 | 土星探测器(历史数据) |
| Perseverance | -168 | 火星车 |
行星
| 名称 | ID |
|---|---|
| Sun | 10 |
| Mercury | 199 |
| Venus | 299 |
| Earth | 399 |
| Mars | 499 |
| Jupiter | 599 |
| Saturn | 699 |
| Uranus | 799 |
| Neptune | 899 |
3. 3D 可视化功能
基础功能
- 太阳系 3D 场景渲染(日心坐标系)
- 行星纹理贴图(diffuse, normal, specular maps)
- 探测器 3D 模型加载(GLB 格式)
- 轨道线绘制(时间序列连线)
- 星空背景(Skybox)
交互功能(进阶)
- OrbitControls: 旋转、缩放、平移视角
- 点击聚焦: 点击探测器/行星,相机平滑飞向目标
- 信息面板: 显示选中物体的详细信息
- 名称、距离太阳距离、速度
- 最近的行星及距离
- 时间选择器: 用户选择起止时间查看历史位置
- 动态缩放: 解决尺度问题(远看时放大物体)
4. 尺度处理策略
问题: 太阳系空间巨大,真实比例下行星会小到看不见
解决方案:
- 坐标系统使用真实 AU 单位(计算准确)
- 渲染时应用动态缩放:
- 远景:行星和探测器放大 1000-10000 倍
- 近景:逐渐恢复真实比例
- 探测器在远景时显示为发光图标,近景时显示 3D 模型
外部资源需求
3D 模型(需下载)
- 来源: https://nasa3d.arc.nasa.gov/models
- 格式: GLB/GLTF
- 存放位置:
frontend/public/models/ - 需要的模型:
- Voyager 1 & 2
- New Horizons
- Parker Solar Probe
- Juno
- Cassini
- Perseverance
行星纹理(需下载)
- 来源: https://www.solarsystemscope.com/textures/
- 格式: JPG/PNG (2K 或 4K)
- 存放位置:
frontend/public/textures/ - 每个行星需要:
{planet}_diffuse.jpg- 颜色贴图{planet}_normal.jpg- 法线贴图(可选)earth_specular.jpg- 地球高光贴图(仅地球)
项目结构
cosmo/
├── backend/
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # FastAPI 入口
│ │ ├── config.py # 配置
│ │ ├── models/
│ │ │ ├── __init__.py
│ │ │ └── celestial.py # 数据模型
│ │ ├── services/
│ │ │ ├── __init__.py
│ │ │ ├── horizons.py # JPL Horizons 查询
│ │ │ └── cache.py # 数据缓存
│ │ └── api/
│ │ ├── __init__.py
│ │ └── routes.py # API 路由
│ ├── requirements.txt
│ └── .env.example
├── frontend/
│ ├── src/
│ │ ├── App.tsx
│ │ ├── main.tsx
│ │ ├── components/
│ │ │ ├── Scene.tsx # 主场景
│ │ │ ├── CelestialBody.tsx
│ │ │ ├── Probe.tsx
│ │ │ ├── OrbitLine.tsx
│ │ │ ├── InfoPanel.tsx
│ │ │ └── TimeSelector.tsx
│ │ ├── hooks/
│ │ │ └── useSpaceData.ts
│ │ ├── types/
│ │ │ └── index.ts
│ │ └── utils/
│ │ └── api.ts
│ ├── public/
│ │ ├── models/ # 探测器 3D 模型
│ │ └── textures/ # 行星纹理
│ ├── package.json
│ ├── tsconfig.json
│ ├── vite.config.ts
│ └── tailwind.config.js
├── PROJECT.md # 本文件
├── IMPLEMENTATION_PLAN.md # 实施计划
└── README.md
API 设计
端点
GET /api/celestial/positions
获取指定时间的天体位置
Query Parameters:
start_time: ISO 8601 格式(可选,默认为当前时间)end_time: ISO 8601 格式(可选)step: 时间步长,如 "1d"(可选,默认 "1d")
Response:
{
"timestamp": "2025-11-26T00:00:00Z",
"bodies": [
{
"id": "-31",
"name": "Voyager 1",
"type": "probe",
"positions": [
{
"time": "2025-11-26T00:00:00Z",
"x": 160.5,
"y": 20.3,
"z": -15.2
}
]
}
]
}
GET /api/celestial/info/{body_id}
获取天体详细信息
Response:
{
"id": "-31",
"name": "Voyager 1",
"type": "probe",
"description": "离地球最远的人造物体",
"launch_date": "1977-09-05",
"status": "active"
}
开发阶段
详见 IMPLEMENTATION_PLAN.md
数据更新策略
- 深空探测器移动缓慢,数据每3天更新一次
- 后端实现缓存机制,避免频繁请求 NASA API
- 缓存存储在内存中(简单实现)或 Redis(生产环境)