668 lines
19 KiB
Markdown
668 lines
19 KiB
Markdown
# Cosmo Phase 4 实施方案:其他恒星系统展示
|
||
|
||
**版本**: 1.0
|
||
**日期**: 2025-12-06
|
||
**状态**: 规划中
|
||
|
||
---
|
||
|
||
## 📋 目录
|
||
|
||
- [1. 现状分析](#1-现状分析)
|
||
- [2. 核心问题](#2-核心问题)
|
||
- [3. 解决方案](#3-解决方案)
|
||
- [4. 数据补充策略](#4-数据补充策略)
|
||
- [5. 实施步骤](#5-实施步骤)
|
||
- [6. 技术细节](#6-技术细节)
|
||
- [7. 风险与挑战](#7-风险与挑战)
|
||
|
||
---
|
||
|
||
## 1. 现状分析
|
||
|
||
### 1.1 数据库现状
|
||
|
||
**已有数据**:
|
||
```sql
|
||
-- 恒星系统表
|
||
star_systems: 579条记录(包括Solar System)
|
||
- 每条记录包含:host_star_name, spectral_type, radius_solar, mass_solar, temperature_k, color等
|
||
- 仅描述主恒星(primary star)
|
||
|
||
-- 天体表
|
||
celestial_bodies: 已有数据
|
||
- system_id = 1 (Solar System): 30条记录(太阳、行星、卫星、探测器等)
|
||
- system_id = 4,5,6,7...: 系外行星数据(约898颗)
|
||
- system_id = 1的恒星: Sun (仅1条)
|
||
- 其他恒星系统的恒星: **缺失!**
|
||
```
|
||
|
||
**数据统计**:
|
||
- ✅ 579个恒星系统信息完整
|
||
- ✅ 898颗系外行星已录入celestial_bodies
|
||
- ❌ 只有太阳系的恒星(Sun)在celestial_bodies中
|
||
- ❌ 其他578个恒星系统的恒星数据缺失
|
||
- ❌ 多星系统(双星、三星等)的伴星数据完全缺失
|
||
|
||
### 1.2 表结构现状
|
||
|
||
**star_systems表**:
|
||
```sql
|
||
CREATE TABLE star_systems (
|
||
id SERIAL PRIMARY KEY,
|
||
host_star_name VARCHAR(200), -- 主恒星名称
|
||
spectral_type VARCHAR(20), -- 主恒星光谱类型
|
||
radius_solar DOUBLE PRECISION,
|
||
mass_solar DOUBLE PRECISION,
|
||
temperature_k DOUBLE PRECISION,
|
||
color VARCHAR(20),
|
||
-- ... 其他字段
|
||
);
|
||
```
|
||
|
||
**celestial_bodies表**:
|
||
```sql
|
||
CREATE TABLE celestial_bodies (
|
||
id VARCHAR(50) PRIMARY KEY,
|
||
system_id INTEGER REFERENCES star_systems(id), -- ✅ 已有外键
|
||
name VARCHAR(200),
|
||
type VARCHAR(50), -- 支持: star, planet, dwarf_planet, satellite, probe, comet
|
||
-- ... 其他字段
|
||
);
|
||
```
|
||
|
||
**关键发现**:
|
||
- ✅ `celestial_bodies`已有`system_id`外键,架构设计正确
|
||
- ✅ `type`字段已支持`star`类型
|
||
- ✅ 数据结构已经支持多恒星系统,只是数据缺失
|
||
|
||
---
|
||
|
||
## 2. 核心问题
|
||
|
||
### 问题1:恒星数据缺失
|
||
|
||
**现象**:
|
||
- `star_systems`表只记录主恒星信息,没有将恒星作为独立天体存入`celestial_bodies`
|
||
- 导致其他恒星系统无法像太阳系一样展示恒星
|
||
|
||
**影响**:
|
||
- 无法进入其他恒星系统视图(因为没有中心恒星)
|
||
- 无法展示多星系统(如双星、三星系统)
|
||
- 缺少恒星的3D模型、纹理资源
|
||
|
||
### 问题2:多星系统支持
|
||
|
||
**现实情况**:
|
||
- 约50%的恒星系统是多星系统(双星、三星等)
|
||
- 例如:
|
||
- **Alpha Centauri**: 三星系统(A, B, Proxima)
|
||
- **Sirius**: 双星系统(A, B)
|
||
- **61 Cygni**: 双星系统(A, B)
|
||
|
||
**当前限制**:
|
||
- `star_systems`表的`host_star_name`只能记录一个恒星
|
||
- 没有记录伴星(companion stars)的数据
|
||
|
||
### 问题3:展示逻辑
|
||
|
||
**问题**:
|
||
- 太阳系模式已实现完整的3D展示(行星、卫星、轨道、探测器)
|
||
- 其他恒星系统是否也采用相同模式?
|
||
- 多星系统如何展示恒星轨道?
|
||
|
||
---
|
||
|
||
## 3. 解决方案
|
||
|
||
### 3.1 方案概述
|
||
|
||
**核心策略**:复用现有架构,补充恒星数据
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ star_systems │
|
||
│ (系统级元数据:位置、距离、系统名称) │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
│
|
||
│ system_id (外键)
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────┐
|
||
│ celestial_bodies │
|
||
│ │
|
||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||
│ │ type=star│ │type=planet│ │type=star │ │type=planet│ │
|
||
│ │ (主恒星) │ │ (行星1) │ │ (伴星) │ │ (行星2) │ │
|
||
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
||
│ │
|
||
│ - 主恒星和伴星都作为 type='star' 存储 │
|
||
│ - 通过 metadata/extra_data 区分主星和伴星 │
|
||
│ - 行星归属于整个系统,不特定于某颗恒星 │
|
||
└─────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 3.2 数据模型设计
|
||
|
||
#### 方案A:推荐方案 - 复用celestial_bodies
|
||
|
||
**优点**:
|
||
- ✅ 无需修改表结构
|
||
- ✅ 统一管理所有天体
|
||
- ✅ 复用现有的3D渲染、资源管理逻辑
|
||
- ✅ 简化查询和关联
|
||
|
||
**实现**:
|
||
|
||
```sql
|
||
-- 1. 为每个恒星系统添加主恒星记录
|
||
INSERT INTO celestial_bodies (
|
||
id, -- 'star-{system_id}-primary'
|
||
system_id, -- 外键指向star_systems
|
||
name, -- 从star_systems.host_star_name复制
|
||
name_zh,
|
||
type, -- 'star'
|
||
metadata -- JSON: {"star_role": "primary", "spectral_type": "G2V", ...}
|
||
) SELECT ...;
|
||
|
||
-- 2. 为多星系统添加伴星记录(如果有)
|
||
INSERT INTO celestial_bodies (
|
||
id, -- 'star-{system_id}-companion-{n}'
|
||
system_id,
|
||
name, -- 伴星名称
|
||
type, -- 'star'
|
||
metadata -- JSON: {"star_role": "companion", "primary_star_id": "star-X-primary"}
|
||
) ...;
|
||
```
|
||
|
||
**metadata字段结构**:
|
||
```json
|
||
{
|
||
"star_role": "primary", // 或 "companion"
|
||
"spectral_type": "G2V",
|
||
"radius_solar": 1.0,
|
||
"mass_solar": 1.0,
|
||
"temperature_k": 5778,
|
||
"luminosity_solar": 1.0,
|
||
"binary_system": true, // 是否为双星系统
|
||
"orbital_period_days": 79.91, // 双星轨道周期(如果是伴星)
|
||
"semi_major_axis_au": 23.7 // 双星系统的半长轴
|
||
}
|
||
```
|
||
|
||
#### 方案B:备选方案 - 创建新表(不推荐)
|
||
|
||
创建专门的`stars`表来存储恒星数据。
|
||
|
||
**缺点**:
|
||
- ❌ 增加表复杂度
|
||
- ❌ 需要额外的关联查询
|
||
- ❌ 恒星和行星管理分离,逻辑复杂
|
||
|
||
**结论**:不采用此方案。
|
||
|
||
### 3.3 展示逻辑设计
|
||
|
||
#### 单星系统(如太阳系、Proxima Centauri)
|
||
|
||
```
|
||
展示模式:与太阳系相同
|
||
- 中心恒星
|
||
- 行星轨道
|
||
- 卫星
|
||
- 相机聚焦逻辑相同
|
||
```
|
||
|
||
#### 双星系统(如Alpha Centauri A+B)
|
||
|
||
```
|
||
展示模式A:质心为中心
|
||
┌─────────────────────────────────────┐
|
||
│ │
|
||
│ ⭐ Star A ●质心 ⭐ Star B │
|
||
│ (轨道) (轨道) │
|
||
│ │
|
||
│ 🪐 Planet 1 (绕质心运行) │
|
||
│ 🪐 Planet 2 │
|
||
└─────────────────────────────────────┘
|
||
|
||
展示模式B:主星为中心
|
||
┌─────────────────────────────────────┐
|
||
│ ⭐ Star A (中心) │
|
||
│ │
|
||
│ ⭐ Star B (轨道) │
|
||
│ │
|
||
│ 🪐 Planet 1 (绕A运行) │
|
||
│ 🪐 Planet 2 (绕A运行) │
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
**推荐**:Phase 4先实现**模式B**(简化版),质心模式留待Phase 5。
|
||
|
||
#### 三星系统(如Alpha Centauri A+B+Proxima)
|
||
|
||
```
|
||
展示模式:分层展示
|
||
主系统:A + B (双星)
|
||
外围:Proxima (远距离伴星)
|
||
|
||
暂不实现,Phase 5考虑
|
||
```
|
||
|
||
### 3.4 用户交互流程
|
||
|
||
```
|
||
用户在银河视图点击恒星系统
|
||
↓
|
||
判断系统类型
|
||
↓
|
||
┌─────┴─────┐
|
||
│ │
|
||
单星系统 多星系统
|
||
│ │
|
||
└─────┬─────┘
|
||
↓
|
||
进入恒星系统视图
|
||
(类似太阳系视图)
|
||
↓
|
||
显示:
|
||
- 恒星(们)
|
||
- 行星轨道
|
||
- 行星
|
||
- (未来:卫星)
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 数据补充策略
|
||
|
||
### 4.1 恒星数据来源
|
||
|
||
**数据源**:`star_systems`表已有完整的主恒星数据
|
||
|
||
**需要补充的数据**:
|
||
|
||
1. **主恒星记录** (579条)
|
||
- 从`star_systems`表提取
|
||
- 创建对应的`celestial_bodies`记录
|
||
|
||
2. **伴星数据** (约100-150条,估计)
|
||
- 需要从外部数据源查询
|
||
- 候选数据源:
|
||
- SIMBAD数据库
|
||
- Washington Double Star Catalog
|
||
- NASA Exoplanet Archive的二进制恒星信息
|
||
|
||
3. **位置和轨道数据**
|
||
- 主恒星:位置 (0, 0, 0) 相对于系统质心
|
||
- 伴星:需要轨道参数(半长轴、周期、偏心率等)
|
||
|
||
### 4.2 数据迁移脚本
|
||
|
||
**步骤1:生成主恒星记录**
|
||
|
||
```python
|
||
# 脚本位置:backend/scripts/populate_stars.py
|
||
|
||
import asyncio
|
||
from app.db import get_db
|
||
from app.models.db.star_system import StarSystem
|
||
from app.models.db.celestial_body import CelestialBody
|
||
|
||
async def populate_primary_stars():
|
||
"""为每个恒星系统创建主恒星记录"""
|
||
db = await get_db()
|
||
|
||
# 获取所有恒星系统
|
||
systems = await db.fetch_all(
|
||
"SELECT * FROM star_systems ORDER BY id"
|
||
)
|
||
|
||
for system in systems:
|
||
# 创建主恒星
|
||
star_id = f"star-{system['id']}-primary"
|
||
|
||
await db.execute(
|
||
"""
|
||
INSERT INTO celestial_bodies (
|
||
id, system_id, name, name_zh, type,
|
||
description, metadata, is_active
|
||
) VALUES (
|
||
$1, $2, $3, $4, 'star',
|
||
$5, $6, TRUE
|
||
)
|
||
ON CONFLICT (id) DO UPDATE SET
|
||
name = EXCLUDED.name,
|
||
metadata = EXCLUDED.metadata
|
||
""",
|
||
star_id,
|
||
system['id'],
|
||
system['host_star_name'],
|
||
system['name_zh'].replace('系统', '').replace('System', '').strip(),
|
||
f"光谱类型: {system['spectral_type'] or 'Unknown'}",
|
||
{
|
||
"star_role": "primary",
|
||
"spectral_type": system['spectral_type'],
|
||
"radius_solar": system['radius_solar'],
|
||
"mass_solar": system['mass_solar'],
|
||
"temperature_k": system['temperature_k'],
|
||
"luminosity_solar": system['luminosity_solar'],
|
||
"color": system['color']
|
||
}
|
||
)
|
||
|
||
# 创建默认位置 (0, 0, 0)
|
||
await db.execute(
|
||
"""
|
||
INSERT INTO positions (
|
||
body_id, time, x, y, z, source
|
||
) VALUES (
|
||
$1, NOW(), 0, 0, 0, 'calculated'
|
||
)
|
||
""",
|
||
star_id
|
||
)
|
||
|
||
print(f"✅ 已创建 {len(systems)} 条主恒星记录")
|
||
```
|
||
|
||
**步骤2:识别多星系统**
|
||
|
||
```python
|
||
# 基于恒星名称模式识别多星系统
|
||
BINARY_PATTERNS = [
|
||
r'(.+)\s+A\s*$', # "Alpha Cen A"
|
||
r'(.+)\s+[AB]\s+System', # "Sirius A System"
|
||
]
|
||
|
||
def identify_binary_systems(systems):
|
||
"""识别可能的双星系统"""
|
||
binary_candidates = []
|
||
|
||
for system in systems:
|
||
name = system['name']
|
||
for pattern in BINARY_PATTERNS:
|
||
if re.match(pattern, name):
|
||
binary_candidates.append(system)
|
||
break
|
||
|
||
return binary_candidates
|
||
```
|
||
|
||
**步骤3:补充伴星数据(手动/半自动)**
|
||
|
||
```sql
|
||
-- 示例:Alpha Centauri系统
|
||
-- 主星:Alpha Cen A (已由脚本生成)
|
||
-- 伴星:Alpha Cen B
|
||
|
||
INSERT INTO celestial_bodies (
|
||
id, system_id, name, name_zh, type, description, metadata
|
||
) VALUES (
|
||
'star-XXX-companion-1',
|
||
(SELECT id FROM star_systems WHERE name = 'Alpha Cen A System'),
|
||
'Alpha Centauri B',
|
||
'半人马座α星B',
|
||
'star',
|
||
'光谱类型: K1V',
|
||
'{
|
||
"star_role": "companion",
|
||
"spectral_type": "K1V",
|
||
"radius_solar": 0.86,
|
||
"mass_solar": 0.93,
|
||
"temperature_k": 5260,
|
||
"luminosity_solar": 0.5,
|
||
"orbital_period_days": 29200,
|
||
"semi_major_axis_au": 23.7,
|
||
"eccentricity": 0.5179,
|
||
"primary_star_id": "star-XXX-primary"
|
||
}'::jsonb
|
||
);
|
||
```
|
||
|
||
### 4.3 数据验证
|
||
|
||
```sql
|
||
-- 验证查询1:每个系统的恒星数量
|
||
SELECT
|
||
ss.name,
|
||
COUNT(cb.id) FILTER (WHERE cb.type = 'star') as star_count,
|
||
COUNT(cb.id) FILTER (WHERE cb.type = 'planet') as planet_count
|
||
FROM star_systems ss
|
||
LEFT JOIN celestial_bodies cb ON ss.id = cb.system_id
|
||
GROUP BY ss.id, ss.name
|
||
ORDER BY star_count DESC, planet_count DESC
|
||
LIMIT 20;
|
||
|
||
-- 验证查询2:多星系统列表
|
||
SELECT
|
||
ss.name,
|
||
array_agg(cb.name) as stars
|
||
FROM star_systems ss
|
||
JOIN celestial_bodies cb ON ss.id = cb.system_id
|
||
WHERE cb.type = 'star'
|
||
GROUP BY ss.id, ss.name
|
||
HAVING COUNT(cb.id) > 1;
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 实施步骤
|
||
|
||
### Phase 4.1: 数据准备 (预计1-2小时)
|
||
|
||
**任务**:
|
||
- [x] 创建数据迁移脚本 `populate_stars.py`
|
||
- [ ] 执行脚本,生成579条主恒星记录
|
||
- [ ] 为所有主恒星创建默认位置 (0,0,0)
|
||
- [ ] 数据验证
|
||
|
||
**验收标准**:
|
||
```sql
|
||
-- 应返回579(所有系统都有主恒星)
|
||
SELECT COUNT(DISTINCT system_id)
|
||
FROM celestial_bodies
|
||
WHERE type = 'star';
|
||
```
|
||
|
||
### Phase 4.2: 后端API扩展 (预计1小时)
|
||
|
||
**任务**:
|
||
- [ ] 扩展 `/star-systems/{id}/bodies` API
|
||
- 当前返回:行星列表
|
||
- 新增返回:恒星列表
|
||
- [ ] 新增 `/star-systems/{id}/view` API
|
||
- 返回完整的系统视图数据(恒星+行星+轨道)
|
||
|
||
**API设计**:
|
||
```python
|
||
# GET /star-systems/{id}/view
|
||
{
|
||
"system": {
|
||
"id": 479,
|
||
"name": "Proxima Cen System",
|
||
"name_zh": "比邻星系统"
|
||
},
|
||
"stars": [
|
||
{
|
||
"id": "star-479-primary",
|
||
"name": "Proxima Centauri",
|
||
"type": "star",
|
||
"metadata": {...}
|
||
}
|
||
],
|
||
"planets": [
|
||
{
|
||
"id": "...",
|
||
"name": "Proxima Cen b",
|
||
"type": "planet",
|
||
...
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### Phase 4.3: 前端展示实现 (预计2-3小时)
|
||
|
||
**任务**:
|
||
- [ ] 创建 `StarSystemScene.tsx` 组件
|
||
- 类似 `Scene.tsx`,但渲染其他恒星系统
|
||
- 支持单星系统展示
|
||
- [ ] 修改 `GalaxyScene.tsx`
|
||
- 点击恒星系统后,跳转到 `StarSystemScene`
|
||
- 或者:弹出全屏模式展示该系统
|
||
- [ ] 实现恒星3D渲染
|
||
- 复用 `BodyViewer` 组件
|
||
- 根据 `spectral_type` 和 `temperature_k` 动态选择颜色
|
||
|
||
**UI流程**:
|
||
```
|
||
GalaxyScene (银河视图)
|
||
│
|
||
│ 点击恒星系统
|
||
↓
|
||
StarSystemScene (恒星系统视图)
|
||
│
|
||
├─ 中心恒星 (3D球体)
|
||
├─ 行星轨道
|
||
├─ 行星
|
||
└─ 相机控制 (复用太阳系模式的聚焦逻辑)
|
||
```
|
||
|
||
### Phase 4.4: 多星系统支持 (Phase 5预留)
|
||
|
||
**任务**:
|
||
- [ ] 识别双星系统
|
||
- [ ] 补充伴星数据
|
||
- [ ] 实现双星轨道渲染
|
||
- [ ] 质心计算和相机调整
|
||
|
||
**暂不实施**,先完成单星系统展示。
|
||
|
||
---
|
||
|
||
## 6. 技术细节
|
||
|
||
### 6.1 恒星颜色映射
|
||
|
||
根据光谱类型和温度自动生成恒星颜色:
|
||
|
||
```typescript
|
||
function getStarColor(spectralType: string, temperature: number): string {
|
||
// 优先使用数据库中的color字段
|
||
// 如果没有,根据光谱类型推断
|
||
|
||
const spectral = spectralType?.charAt(0).toUpperCase();
|
||
|
||
const colorMap: Record<string, string> = {
|
||
'O': '#9bb0ff', // 蓝色 (> 30000K)
|
||
'B': '#aabfff', // 蓝白色 (10000-30000K)
|
||
'A': '#cad7ff', // 白色 (7500-10000K)
|
||
'F': '#f8f7ff', // 黄白色 (6000-7500K)
|
||
'G': '#fff4ea', // 黄色 (5200-6000K) - 太阳型
|
||
'K': '#ffd2a1', // 橙色 (3700-5200K)
|
||
'M': '#ffcc6f', // 红色 (2400-3700K)
|
||
};
|
||
|
||
return colorMap[spectral] || '#ffffff';
|
||
}
|
||
```
|
||
|
||
### 6.2 坐标系统
|
||
|
||
**恒星系统内部坐标系**:
|
||
- 原点:系统质心(单星系统即恒星中心)
|
||
- 单位:AU(天文单位)
|
||
- 坐标系:右手坐标系,Y轴向上
|
||
|
||
**多星系统**:
|
||
- 主星位置:相对于质心的偏移
|
||
- 伴星位置:轨道计算
|
||
- 行星位置:相对于系统质心
|
||
|
||
### 6.3 渲染优化
|
||
|
||
**LOD (Level of Detail)**:
|
||
- 近距离:完整渲染恒星纹理
|
||
- 中距离:简化球体
|
||
- 远距离:光点+标签
|
||
|
||
**性能考虑**:
|
||
- 恒星数量:通常1-3颗
|
||
- 行星数量:0-8颗
|
||
- 总体复杂度低于太阳系
|
||
|
||
---
|
||
|
||
## 7. 风险与挑战
|
||
|
||
### 7.1 数据质量风险
|
||
|
||
**风险**:伴星数据不完整或不准确
|
||
|
||
**缓解措施**:
|
||
- Phase 4只展示主恒星
|
||
- 伴星数据作为增强功能,逐步补充
|
||
|
||
### 7.2 多星系统复杂度
|
||
|
||
**风险**:双星/三星系统的轨道计算和渲染复杂
|
||
|
||
**缓解措施**:
|
||
- Phase 4仅支持单星系统
|
||
- Phase 5再实现多星系统
|
||
|
||
### 7.3 用户体验一致性
|
||
|
||
**风险**:不同恒星系统的数据完整度差异导致体验不一致
|
||
|
||
**缓解措施**:
|
||
- 统一的UI降级策略
|
||
- 缺少数据时显示占位符
|
||
- 提供"数据来源"说明
|
||
|
||
---
|
||
|
||
## 8. 时间估算
|
||
|
||
| 阶段 | 任务 | 预计时间 |
|
||
|------|------|---------|
|
||
| Phase 4.1 | 数据准备 | 1-2小时 |
|
||
| Phase 4.2 | 后端API | 1小时 |
|
||
| Phase 4.3 | 前端展示 | 2-3小时 |
|
||
| **总计** | | **4-6小时** |
|
||
|
||
---
|
||
|
||
## 9. 成功标准
|
||
|
||
### 最小可行产品 (MVP)
|
||
|
||
- [x] 所有579个恒星系统都有主恒星记录
|
||
- [ ] 用户可以从银河视图进入任意恒星系统
|
||
- [ ] 恒星系统视图正确显示:
|
||
- 中心恒星(3D球体,正确颜色)
|
||
- 行星轨道
|
||
- 行星
|
||
- [ ] 相机聚焦和控制与太阳系模式一致
|
||
|
||
### 增强功能(Phase 5)
|
||
|
||
- [ ] 支持双星系统展示
|
||
- [ ] 恒星轨道动画
|
||
- [ ] 行星卫星展示
|
||
- [ ] 更丰富的恒星视觉效果(日冕、耀斑等)
|
||
|
||
---
|
||
|
||
## 10. 参考资料
|
||
|
||
- NASA Exoplanet Archive: https://exoplanetarchive.ipac.caltech.edu/
|
||
- SIMBAD Astronomical Database: http://simbad.u-strasbg.fr/
|
||
- Washington Double Star Catalog: https://www.usno.navy.mil/USNO/astrometry/optical-IR-prod/wds
|
||
- 恒星光谱分类: https://en.wikipedia.org/wiki/Stellar_classification
|
||
|
||
---
|
||
|
||
**文档维护者**: Cosmo Development Team
|
||
**最后更新**: 2025-12-06
|