feat: 完善日月食与月掩几何链路并扩展历法接口

- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑
- 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口
- 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界
- 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名
- 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验
- 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口
- 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
This commit is contained in:
2026-09-17 12:27:40 +08:00
parent 9ee2163cc7
commit 2bf8478639
428 changed files with 85981 additions and 7998 deletions
+35
View File
@@ -0,0 +1,35 @@
package basic
import (
"math"
"testing"
)
// GetJieqiLoops 的黄经必须归化到 (0,360]:loop>31 时旧实现把 >360° 的角度直接交给 GetJQTime,
// 那里 Newton 迭代静默失败,返回 9 个 NaN;loop<=0 旧实现还会 makeslice panic。
func TestGetJieqiLoopsNormalizesAngleAndGuardsLoop(t *testing.T) {
short := GetJieqiLoops(2024, 25)
long := GetJieqiLoops(2024, 40)
if len(long) != 40 {
t.Fatalf("loop=40 length = %d", len(long))
}
for index, value := range long {
if math.IsNaN(value) || math.IsInf(value, 0) {
t.Fatalf("loop=40 index %d is not finite: %v", index, value)
}
if index > 0 && value <= long[index-1] {
t.Fatalf("loop=40 index %d is not increasing: %v <= %v", index, value, long[index-1])
}
}
for index := range short {
if math.Float64bits(short[index]) != math.Float64bits(long[index]) {
t.Fatalf("loop=25 index %d changed when loop grows: %v vs %v", index, short[index], long[index])
}
}
if got := GetJieqiLoops(2024, 0); got != nil {
t.Fatalf("loop=0 = %v, want nil", got)
}
if got := GetJieqiLoops(2024, -3); got != nil {
t.Fatalf("negative loop = %v, want nil (no panic)", got)
}
}