cosmo/RAODMAP.md

331 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

这是一个基于我们需要实现的功能、技术选型以及数据策略整理而成的完整产品路线图Roadmap。你可以直接将此内容保存为 `roadmap.md` 文件,用于项目管理或开发指引。
-----
# Product Roadmap: 深空与系外行星可视化系统
## 1\. 项目愿景 (Product Vision)
构建一个基于 Web 的 3D 可视化系统,能够精确展示太阳系内主要天体及人造探测器(如旅行者号)的实时位置,并能无缝切换至恒星际视角,探索临近的系外行星系统。系统强调科学数据的准确性(基于 NASA 数据)与视觉表现的真实感。
## 2\. 技术架构 (Technical Architecture)
### 后端 (Data Processing)
* **语言:** Python 3.x
* **核心库:**
* `astroquery`: 连接 NASA JPL Horizons (太阳系) 和 NASA Exoplanet Archive (系外行星)。
* `skyfield` / `astropy`: 处理时间坐标转换、球坐标转直角坐标。
* `numpy`: 矢量计算。
* **输出:** JSON 格式的静态数据或 RESTful API。
### 前端 (Visualization)
* **引擎:** Three.js (WebGL)
* **核心技术:**
* `OrbitControls`: 视角控制。
* `GLTFLoader`: 加载探测器 3D 模型。
* `LogarithmicDepthBuffer`: 解决超大空间尺度下的深度闪烁问题。
* **UI 框架:** Vue / React / Vanilla JS (根据喜好选择,用于覆盖层 UI)。
-----
## 3\. 开发路线规划 (Development Phases)
### Phase 1: 太阳系核心架构 (Core Solar System)
**目标:** 搭建基础 3D 场景,实现太阳、八大行星及关键深空探测器的实时定位。
- [ ] **数据层搭建 (Python)**
- [ ] 集成 `astroquery.jplhorizons`
- [ ] 实现以太阳为原点 (Heliocentric) 的坐标获取脚本。
- [ ] 确定单位标准:使用 **天文单位 (AU)** 作为基础单位。
- [ ] 建立目标 ID 列表:八大行星 + Voyager 1/2 + Parker Solar Probe + New Horizons。
- [ ] **可视化原型 (Three.js)**
- [ ] 初始化场景、相机、灯光(点光源 @ 0,0,0
- [ ] 解析 Python 生成的 JSON 数据,放置代表天体的球体。
- [ ] 实现基础的轨道线绘制查询过去1年到未来1年的坐标点连线
- [ ] **探测器模型接入**
- [ ] 下载 NASA 官方 `.glb` 模型 (Voyager, Cassini 等)。
- [ ] 实现 `GLTFLoader` 加载模型替换简单的方块/球体。
### Phase 2: 视觉增强与尺度管理 (Visual Fidelity & Scale)
**目标:** 解决“看不见”的问题,提升渲染真实度。
- [ ] **动态尺度系统 (Dynamic Scaling)**
- [ ] 实现根据摄像机距离动态调整物体大小的算法 (Billboard 模式)。
- [ ] 确保远景能看到图标/放大版星球,近景自动切换为真实比例模型。
- [ ] **纹理与材质 (Textures)**
- [ ] 应用行星高清贴图 (Diffuse + Normal + Specular)。
- [ ] **卫星纹理策略:**
- [ ] 高清卫星 (月球, 木卫二, 土卫六): 使用真实地图。
- [ ] 通用卫星 (小卫星): 使用程序化生成的岩石/冰块材质。
- [ ] **特殊天体:** 实现太阳的发光效果 (Bloom/Glow) 和土卫六的大气层效果。
- [ ] **交互基础**
- [ ] 实现点击天体列表或 3D 物体,摄像机平滑飞行聚焦 (FlyTo)。
### Phase 3: 恒星际扩展 (Interstellar Expansion)
**目标:** 跳出太阳系,展示临近恒星和系外行星概览。
- [ ] **系外数据获取 (Python)**
- [ ] 集成 `NasaExoplanetArchive`
- [ ] 筛选距离地球最近的 100-500 个恒星系。
- [ ] 坐标转换算法:(RA, Dec, Distance) -\> (x, y, z),统一转换为 **秒差距 (pc)** 或光年单位。
- [ ] **银河系视图 (Galaxy View)**
- [ ] 创建新的 Three.js 场景或使用层级切换。
- [ ] 使用 **粒子系统 (PointsMaterial)** 渲染恒星背景,高性能展示大量恒星。
- [ ] 实现恒星颜色映射:根据光谱类型 (O, B, A, F, G, K, M) 赋予粒子不同颜色。
- [ ] 交互:鼠标悬停粒子显示恒星名称及行星数量。
### Phase 4: 系外行星系统详情 (Exoplanet Systems)
**目标:** 进入特定的系外恒星系,基于轨道参数模拟未知世界。
- [ ] **详细轨道数据**
- [ ] 获取开普勒轨道参数:半长轴、周期、离心率、行星半径、平衡温度。
- [ ] **轨道模拟与渲染**
- [ ] 使用 `EllipseCurve` 绘制椭圆轨道。
- [ ] 基于时间戳计算行星在轨道上的近似位置。
- [ ] **程序化星球外观 (Procedural Appearance)**
- [ ] 建立通用纹理库 (Gas Giant, Rocky, Ice, Lava)。
- [ ] 编写匹配逻辑:根据 `行星半径``温度` 自动分配材质和颜色。
- [ ] *Example:* 半径 \> 4 Earths -\> 气态巨行星纹理。
- [ ] *Example:* 温度 \> 400K -\> 熔岩纹理。
-----
## 4\. 资源清单 (Resources)
### 数据源 (Data Sources)
* **JPL Horizons:** [Web Interface](https://ssd.jpl.nasa.gov/horizons/) (用于 API 参数参考)
* **NASA Exoplanet Archive:** [https://exoplanetarchive.ipac.caltech.edu/](https://exoplanetarchive.ipac.caltech.edu/)
* **SIMBAD / NED:** 深空天体补充数据。
### 美术资产 (Assets)
* **3D Models:** [NASA 3D Resources](https://nasa3d.arc.nasa.gov/models)
* **Planetary Textures:**
* [Solar System Scope](https://www.solarsystemscope.com/textures/) (基础行星)
* [USGS Astrogeology](https://www.google.com/search?q=https://astrogeology.usgs.gov/) (科学级地图)
* [Celestia Motherlode](http://www.celestiamotherlode.net/) (虚构/通用纹理)
* **Map Projection:** 搜索关键词 `Equirectangular Projection`
### 关键 ID 参考 (Horizons ID)
* Sun: `@sun`
* Voyager 1: `-31`
* Voyager 2: `-32`
* New Horizons: `-98`
* Parker Solar Probe: `-96`
* Mars: `499`
* Jupiter: `599`
-----
## 5\. 待解决难点与风险 (Risks & Challenges)
1. **坐标系融合:** 太阳系 (AU) 与恒星际 (pc/LightYear) 跨度过大。
* *Solution:* 采用场景分割 (Scene Switching) 或对数深度缓冲 (Logarithmic Depth Buffer)。
2. **数据缺失:** 许多系外行星缺失半径或温度数据。
* *Solution:* 在后端脚本中设置合理的默认值 (Default Fallback),防止前端崩溃。
3. **性能优化:** 粒子数量过多或模型面数过高。
* *Solution:* 使用 InstancedMesh针对小天体使用低模 (Low-poly) + 法线贴图。
-----
## 6\. 下一步行动 (Next Steps)
1. 运行 Python 脚本,生成 `solar_system_data.json``nearest_stars.json`
2. 搭建 Three.js 基础工程,先把太阳和地球画出来。
3. 下载旅行者号模型,尝试加载到场景中。
这是一个为您准备好的 `roadmap.md` 附录补充内容。为了保持文档整洁,我将 Phase 3 和 Phase 4 的核心逻辑代码整理为了一个 **"Appendix: Key Technical Implementation"** 章节。
您可以直接将以下内容复制并粘贴到之前 `roadmap.md` 文件的底部。
-----
## Appendix: Key Technical Implementation (Phase 3 & 4)
本附录收录了实现恒星际视图Phase 3和系外行星详情页Phase 4的核心代码片段涵盖数据获取与前端渲染逻辑。
### Phase 3: Interstellar View (恒星际视图)
#### 1\. Backend: 获取临近恒星并转换坐标 (Python)
此脚本筛选距离地球最近的恒星,并将天球坐标 (RA/Dec) 转换为笛卡尔坐标 (X/Y/Z)。
```python
# get_nearest_stars.py
from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive
from astropy.coordinates import SkyCoord
from astropy import units as u
import json
def fetch_nearest_stars(limit=1000):
# 1. 查询 NASA Exoplanet Archive (PS Table)
# 筛选条件:距离 < 100 pc (约326光年)
table = NasaExoplanetArchive.query_criteria(
table="ps",
select="hostname, sy_dist, ra, dec, sy_pnum",
where="sy_dist < 100",
order="sy_dist"
)
unique_stars = {}
for row in table:
host_name = str(row['hostname'])
if host_name in unique_stars: continue
# 2. 坐标转换 (Spherical -> Cartesian)
# 核心逻辑:利用 Astropy 将 RA/Dec/Distance 转为 X/Y/Z
dist = float(row['sy_dist'])
coord = SkyCoord(ra=float(row['ra'])*u.deg, dec=float(row['dec'])*u.deg, distance=dist*u.pc)
unique_stars[host_name] = {
"name": host_name,
"distance_pc": dist,
"planet_count": int(row['sy_pnum']),
"pos": {
"x": round(coord.cartesian.x.value, 3),
"y": round(coord.cartesian.y.value, 3),
"z": round(coord.cartesian.z.value, 3)
}
}
if len(unique_stars) >= limit: break
# 输出 JSON
return list(unique_stars.values())
```
#### 2\. Frontend: 高性能星空渲染 (Three.js)
使用 `Points` (粒子系统) 而非 `Mesh` 来渲染数千颗恒星,保证高性能。
```javascript
// StarField.js
function createStarField(starData) {
const geometry = new THREE.BufferGeometry();
const positions = [];
const sizes = []; // 可选:根据恒星大小或距离调整粒子大小
const SCALE_FACTOR = 10; // 视觉缩放系数,避免坐标过于拥挤
starData.forEach(star => {
positions.push(
star.pos.x * SCALE_FACTOR,
star.pos.y * SCALE_FACTOR,
star.pos.z * SCALE_FACTOR
);
sizes.push(1.0); // 默认大小
});
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
// 使用 PointsMaterial
const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.5,
sizeAttenuation: true // 开启透视消隐 (远小近大)
});
const starSystem = new THREE.Points(geometry, material);
return starSystem;
}
```
-----
### Phase 4: Exoplanet Systems (系外行星详情)
#### 1\. Backend: 获取详细轨道参数 (Python)
获取开普勒轨道要素,用于前端绘制椭圆轨道和模拟运动。
```python
# get_system_details.py
def fetch_system_details(hostname):
# 查询指定恒星系的所有行星参数
# pl_orbsmax: 半长轴 (AU), pl_orbper: 周期 (Days), pl_orbeccen: 离心率
# pl_rade: 半径 (Earth Radii), pl_eqt: 平衡温度 (K)
table = NasaExoplanetArchive.query_criteria(
table="ps",
select="pl_name, pl_orbsmax, pl_orbper, pl_orbeccen, pl_rade, pl_eqt",
where=f"hostname = '{hostname}'"
)
planets = []
for row in table:
planets.append({
"name": str(row['pl_name']),
"a": float(row['pl_orbsmax']) if row['pl_orbsmax'] else 0.1, # Semi-major axis
"e": float(row['pl_orbeccen']) if row['pl_orbeccen'] else 0.0, # Eccentricity
"period": float(row['pl_orbper']) if row['pl_orbper'] else 365.0,
"radius": float(row['pl_rade']) if row['pl_rade'] else 1.0,
"temp": float(row['pl_eqt']) if row['pl_eqt'] else 300
})
return planets
```
#### 2\. Frontend: 轨道绘制与材质程序化匹配 (Three.js)
**A. 绘制椭圆轨道:**
```javascript
function createOrbit(a, e) {
// a: 半长轴 (AU), e: 离心率
// EllipseCurve 参数: xRadius, yRadius (b = a * sqrt(1-e^2))
const b = a * Math.sqrt(1 - (e * e));
const curve = new THREE.EllipseCurve(
0, 0, // 中心 X, Y
a, b, // X半径, Y半径
0, 2 * Math.PI // 0 到 360度
);
const points = curve.getPoints(128);
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0x444444 });
const orbit = new THREE.Line(geometry, material);
// 【关键】偏移修正:将椭圆焦点对齐到恒星位置 (0,0)
// 偏移量 c = a * e
orbit.position.x = - (a * e);
// 旋转 90度让其平躺在 XZ 平面上
orbit.rotation.x = -Math.PI / 2;
return orbit;
}
```
**B. 材质程序化匹配 (Procedural Texturing):**
根据数据猜测行星长什么样。
```javascript
// 简单的外观推断逻辑
function getPlanetTexture(radius, temp) {
const PATH = 'assets/textures/generic/';
// 1. 气态巨行星 (半径 > 4倍地球)
if (radius > 4.0) {
return textureLoader.load(PATH + 'gas_giant_bw.jpg'); // 配合 color 属性染色
}
// 2. 熔岩行星 (温度 > 400K)
if (temp > 400) {
return textureLoader.load(PATH + 'magma.jpg');
}
// 3. 冰冻星球 (温度 < 150K)
if (temp < 150) {
return textureLoader.load(PATH + 'ice.jpg');
}
// 4. 宜居带/岩石行星 (默认)
return textureLoader.load(PATH + 'rocky_atmosphere.jpg');
}
```