cosmo/PHASE4_PLAN.md

19 KiB
Raw Permalink Blame History

Cosmo Phase 4 实施方案:其他恒星系统展示

版本: 1.0 日期: 2025-12-06 状态: 规划中


📋 目录


1. 现状分析

1.1 数据库现状

已有数据

-- 恒星系统表
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表

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表

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渲染、资源管理逻辑
  • 简化查询和关联

实现

-- 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字段结构

{
  "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生成主恒星记录

# 脚本位置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识别多星系统

# 基于恒星名称模式识别多星系统
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补充伴星数据手动/半自动)

-- 示例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 数据验证

-- 验证查询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小时)

任务

  • 创建数据迁移脚本 populate_stars.py
  • 执行脚本生成579条主恒星记录
  • 为所有主恒星创建默认位置 (0,0,0)
  • 数据验证

验收标准

-- 应返回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设计

# 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_typetemperature_k 动态选择颜色

UI流程

GalaxyScene (银河视图)
    │
    │ 点击恒星系统
    ↓
StarSystemScene (恒星系统视图)
    │
    ├─ 中心恒星 (3D球体)
    ├─ 行星轨道
    ├─ 行星
    └─ 相机控制 (复用太阳系模式的聚焦逻辑)

Phase 4.4: 多星系统支持 (Phase 5预留)

任务

  • 识别双星系统
  • 补充伴星数据
  • 实现双星轨道渲染
  • 质心计算和相机调整

暂不实施,先完成单星系统展示。


6. 技术细节

6.1 恒星颜色映射

根据光谱类型和温度自动生成恒星颜色:

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)

  • 所有579个恒星系统都有主恒星记录
  • 用户可以从银河视图进入任意恒星系统
  • 恒星系统视图正确显示:
    • 中心恒星3D球体正确颜色
    • 行星轨道
    • 行星
  • 相机聚焦和控制与太阳系模式一致

增强功能Phase 5

  • 支持双星系统展示
  • 恒星轨道动画
  • 行星卫星展示
  • 更丰富的恒星视觉效果(日冕、耀斑等)

10. 参考资料


文档维护者: Cosmo Development Team 最后更新: 2025-12-06