# 架构

[返回首页](../README.md) · [开发与测试](./development.md)

## 包与依赖方向

仓库是一个 npm workspace，包含一个天文与历法核心、三个规则包和两个可选数据／星历包：

| 包 | 实现与发布内容 | 职责 |
| --- | --- | --- |
| `js-ephemeris-lite` | 纯 JavaScript、TypeScript 类型声明 | 星历、天象、时间、中国历法与干支 |
| `bazi-lite` | TypeScript 编译到 `dist` | 四柱、十神、神煞、起运大运与反查 |
| `ziwei-lite` | TypeScript 编译到 `dist` | 紫微命盘、流运、自定义规则与反查 |
| `huangli-lite` | 直接发布 JavaScript 源文件及类型声明 | 每日宜忌、神煞、节日与风水规则 |
| `star-catalog-lite` | TSC1 二进制星表及 JavaScript 读取入口 | 可选亮星数据、传统星名与星座连线恒星 |
| `asteroid-ephemeris-lite` | JavaScript 求值器及压缩拟合系数 | 可选小行星和半人马小行星位置 |

五个 workspace 包均声明依赖 `js-ephemeris-lite`，核心包不反向依赖它们。
六个包均可单独安装和发布；workspace 只负责联合开发、测试及版本协作。

## 核心模块层次

| 层 | 公共模块 | 职责 |
| --- | --- | --- |
| 几何星历与坐标 | `ephemeris`, `coordinates` | 日月行星位置、速度、岁差章动与坐标变换 |
| 视位置 | `apparent`, `phenomena` | 光行时、光行差、照明、视直径与观测量 |
| 通用事件 | `event-search`, `orbital-events` | 黄经、赤经、合冲、留、大距、近远点和交点搜索 |
| 气朔与历法事件 | `calendar-events`, `qi-shuo` | 定气定相、全年节气、七十二候与月相 |
| 中国历法 | `chinese-calendar`, `chinese-era`, `ganzhi` | 农历结构、历史归日、纪年和四柱 |
| 地平观测 | `solar-visibility`, `body-visibility` | 日出日落、天体出没、方位与高度 |
| 日月食几何 | `eclipses` | 日月视位置插值、影锥与椭球相交、地方接触时刻 |
| 应用型日月食查询 | `eclipse-search` | 区间搜索、结构化结果及地方日月食可见性 |
| 时间与钟表 | `time`, `solar-time` | TT/UT1、固定时区、平太阳时与真太阳时 |

这些模块都有正式的包子路径和类型声明，不再属于临时的“开发中”入口。
内部求值器、系数文件和数值工具不是稳定公共 API。物理瞬时与钟表规则始终
分开传递，真太阳时、晚子时规则或历法归日不会改写实际天文瞬时。

## 星历模型与运行时数据

| 文件 | 内容 |
| --- | --- |
| `src/{earth,mercury,…,pluto}-series.js` | 按天体独立存放的行星 L/B/R 表及冥王星拟合表；系数不重复 |
| `src/planet-series.js` | 系数聚合导出，供离线工具和对拍使用；日月运行时不引用此入口 |
| `src/earth-model.js`、`src/sun-moon-ephemeris.js` | 独立地球模型和日月状态 API，对应 `/sun-moon` 子入口 |
| `src/apparent-core.js` | 共享视位置算法，显式接收行星求值器；日月入口不加载其他行星 |
| `src/planet-models.js` | 各行星运行时基底的固定选择 |
| `src/direct-planet-model.js` | 通用 Fourier–多项式 L/B/R 求值器及解析速度 |
| `src/planet-prefix-counts.js` | 行星位置 fast／mid 的每阶保留项数，不含系数副本 |
| `src/moon-series.js` | 离线筛选并校准后的月球分阶表、共享相位及 P/Q 常数 |
| `src/moon-model.js` | 月球共享相位求值与解析速度 |
| `src/moon-prefix-counts.js` | 月球位置 fast／mid 的每阶保留项数，不含系数副本 |
| `src/pluto-model.js` | 冥王星近代模型、后备模型及过渡区 |
| `packages/asteroids/src/` | 可选小行星包的分段连续性处理及压缩系数；不包含在主包中 |
| `src/planet-frame.js` | 行星理论原生系到 J2000 平黄道系的固定变换 |
| `src/nutation-series.js` | IAU 2000B 章动系数 |
| `src/event-series.js` | 定气定相的初值和专用事件模型系数 |
| `src/generated/` | 历史历法归日与中国纪年数据 |

### 八大行星

当前运行时**不直接执行 VSOP2013 椭圆要素算法，也不直接求值原始 TOP2013
表**。发布的各天体系数表是离线生成的折叠模型：

- 水星、金星、地球和火星以完整 VSOP2013 椭圆要素解为理论来源，离线完成
  坐标转换、Fourier／多项式展开和截断选择；
- 木星、土星、天王星和海王星以 TOP2013 L/B/R 表为理论来源，离线换基并
  筛选；
- 两组模型都按 JPL DE441 样本选择项，并把本项目拟合的多项式及周期残差直接
  折进最终系数表，没有运行时外挂修正表；
- 每颗行星只有一套覆盖完整支持区间的全局表，不再按年代切换区域修正。

因此，“VSOP2013”或“TOP2013”描述的是底层理论来源，并不等同于当前包实际
执行的算法。运行时只对已经生成好的 Fourier–多项式 L/B/R 表求值，不解
开普勒方程。

| 对象 | 理论来源与拟合目标 | 运行时基底 | 几何目标点 |
| --- | --- | --- | --- |
| 水星、金星、火星 | VSOP2013 展开 + DE441 残差 | 儒略千年时间幂 `T^n` | 对应行星系统质心 |
| 地球 | VSOP2013 展开 + DE441 残差 | 儒略千年时间幂 `T^n` | 物理地球中心 |
| 木星、土星、天王星、海王星 | TOP2013 + DE441 残差 | 儒略千年时间幂 `T^n` | 行星系统质心 |

地球表在生成阶段已经包含由地月质心到物理地球中心的月球位移，运行时无需
再次求月球并作扣除。旧的分段式天王星、海王星修正和早期 VSOP87 求值器均不
属于当前发布模型。

最终系数仍按 `L0/L1/…`、`B0/B1/…`、`R0/R1/…` 分组，每项为
`A, phase, frequency`。水星至海王星的分组下标都是儒略千年 `T` 的普通时间幂次。

位置计算的 fast／mid 以及事件模型需要裁剪行星级数时，不会把跨越多个时间幂的同频率系数拆开，而是把
同一频率的完整多项式包络作为一个选择单位。生成阶段先形成嵌套的优先级，再把
每个 `Lₙ/Bₙ/Rₙ` 内部按该优先级重排，并在档位计数表中写出各精度档每一阶
应保留多少项。计数表不包含振幅、相位或频率。
运行时只计算每阶前若干项，不再采样、排名或组装子表；完整、fast 和 mid
路径仍共用每颗行星的同一套系数。地球另保留事件求解器所需的更细前缀预算。

时间变量为儒略千年
`T = (jdTT - 2451545) / 365250`。每项贡献为
`T^n * A * cos(phase + frequency * T)`，与经典 VSOP 级数布局一致。L/B 使用弧度，R 使用 AU，
速度由同一表达式解析求导。

### 月球

月球运行时使用一套全局校准的直接分阶表。它以 ELP/MPP02 DE405 模式系数为
理论来源，经离线截断、重排，并把针对 DE441 的拟合修正折进最终相位和系数；
运行时同样没有独立的“原始值 + 修正量”步骤或年代分段。

每项为 `S, C, argumentIndex`，贡献为
`x^n * (S*sin(argument) + C*cos(argument))`，其中
`x = (jdTT - 2451545) / 2922000`。L/B/R 共享相位三角函数及解析导数；L/B
使用弧度，R 使用 km，黄经另加校准后的平均黄经多项式，再经 P/Q 变换进入
库内 J2000 平黄道系。

月球位置三档也在生成阶段以完整共享相位包络排序。每阶只保存一套系数和
fast／mid 每阶保留项数；截断后的 L/B/R 仍共享已经计算过的相位三角函数。

### 冥王星

VSOP2013 官方解本身包含冥王星的 `VSOP2013p9.dat`，但当前发布代码没有把
冥王星接入前述八大行星的 VSOP/TOP 折叠求值路径。`plutoModel` 是另一次
DE441 直接拟合实验冻结下来的两级模型，并非 C++ 仓库中的半解析冥王星表：

- `1600..2200` 年使用一组直接拟合 DE441 9−10（冥王星系统质心相对太阳）的
  L/B/R Chebyshev 多项式。拟合区间向两侧扩至 `1590..2210`，正式表为 384 次，
  三坐标合计 1155 个标量系数。
- 更远日期使用代号 `mixed-low-w95` 的保底级数：以半轨道及外行星频率字典组成
  Fourier–Legendre 基底，再直接拟合 DE441；三坐标各 448 项，共 1344 项。
  选择低阶满秩版本是为了避免高阶试验中的病态矩阵和远端发散。它只保证宽年代
  内返回有限、轨道尺度合理的结果，不是另一套高精度星历。

1590..1600 与 2200..2210 年以五次平滑权重连接，速度包含权重导数；近代
Chebyshev 多项式不会直接向远端外推。C++ 的 96 组多项式相位/振幅模型是另一套
实现，原生支持范围约为 `-3000..3000`，当前 JS 包没有移植或用作后备。
这里也应区分 VSOP2013 理论中“存在冥王星解”和本包实际分发的运行时模型。
适用范围见[冥王星精度说明](./accuracy.md#冥王星)。

### 参考系

行星理论原生黄道系经固定矩阵转换到库内 J2000 平黄道系，位置和速度使用同一
变换；月球使用自身的 P/Q 参考系变换。日期参考面采用 Vondrák 2011 长期岁差
和 IAU 2000B 章动。几何位置、视位置与地平位置是分层接口，调用者不会因为
请求一个几何坐标而隐式得到光行时或观测者视差修正。

## 事件求解

### 定气定相

定气求太阳视黄经达到目标角度的 TT 时刻，定相求月日视黄经差达到目标角度的
TT 时刻。`solveSolarLongitude`、`solveLunarPhase` 和 `solveNewMoon` 接受
`fast`、`mid`、`accurate` 三档，默认 `mid`：

- `fast` 分阶段使用低预算估计，最终太阳／月球主黄经使用完整级数并作固定次数修正；
- `mid` 使用专用事件模型并按容差迭代；
- `accurate` 使用完整库内视位置模型并按容差迭代。

精度通过每次调用的 `{ accuracy }` 或上层查询的 `eventAccuracy` 传入，没有
模块级可变默认值。这里的事件档位不会改变通用位置的默认值；位置函数另行接受
直接的 `accuracy` 字符串，视位置则在自己的选项中选择。日月食仍使用各自固定
模型。`solve…` 返回 `JulianTime`；累计角度的数学层 Fast/Accurate
函数仍返回数值 JD(TT)。详见[时间与历法指南](./time-and-calendar.md)。

### 通用天象搜索

通用事件层用离散扫描寻找候选区间，再用相应状态函数和数值求根器细化。
参考面、几何中心和扫描步长均由具体接口显式表达；搜索区间采用半开区间，
并做边界去重。接口不会共享一套隐式的“当前精度”状态。

### 日月食

内部几何层使用本库日月视位置：日食采用五点位置插值和影锥—椭球相交，
月食采用三维地影与五点三次接触拟合。每场食独立持有插值数据，没有公开的
可变单例计算器。地方日食使用观测者地心向量和日月视半径求接触，再处理地平线截断。

`eclipses` 与 `eclipse-search` 导出同一套现代 API，接受 `Date`、`JulianTime`、
`ZonedTime`、`AstroTime` 或 UT1 JD。只处理天文事件与经纬度，不包含地图、
行政区边界、地名或界线绘制接口。详见[日月食查询](./eclipse-search.md)。

## 时间模型

事件在 TT 上求解，民用钟表、历法和地平观测使用 UT1。`JulianTime` 同时保存
`jdTT`、`jdUT1` 与 `deltaTSeconds`；固定时区显示由
`JulianTime.toZonedTime()` 完成。库采用 `UTC ≈ UT1`，不携带闰秒、TAI 或
实时 EOP 表。

ΔT 在 1953～2027 年使用观测年表、IERS 短期预测及 Catmull–Rom 插值；
2027～2028 年以三次 Hermite 保持数值和一阶导数连续，2028 年起使用长期基线、
15 年余弦项与 18.613 年月交点周期修正组成的实验性未来模型。更早年代使用
S15 分段模型，-820～-720 年之间以三次 Hermite 接续远古长期模型。

农历结构、天文事件时刻与历史归日是不同层次的数据。历史模式可以采用史料中的
定气定朔归日，而现代天文模式使用当前求得的事件时刻和所选日界。详见
[历史历法](./calendar-history.md)。

## 分发与运行边界

根包的所有公开入口都是 ES modules，并提供对应 `.d.ts`。数值系数与历史数据
随 npm 包分发，安装和运行时不下载外部星历，也不需要 Python、Dart、C++ 或
WebAssembly。根包没有运行时依赖；三个规则包只依赖根包。

第三方模型、历史数据、移植算法及各自许可边界见
[中文第三方声明](../THIRD_PARTY_NOTICES.zh-CN.md)和
[英文第三方声明](../THIRD_PARTY_NOTICES.md)。

按需加载边界和体积实测见[日月依赖拆分](module-loading.md)。
