Files
astro/eclipse/svg/lunar_detailed_test.go
T
b612 2bf8478639 feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑
- 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口
- 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界
- 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名
- 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验
- 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口
- 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
2026-09-17 12:27:40 +08:00

71 lines
2.7 KiB
Go

package svg
import (
"math"
"strings"
"testing"
"time"
"b612.me/astro/basic"
)
// 详细版式组合图必须把摘要、穿影示意图与世界可见性底图放在同一页,并带日月地心坐标块与三栏面板。
func TestLunarEclipseDetailedSVGCombinesBothCharts(t *testing.T) {
date := time.Date(2025, time.March, 14, 0, 0, 0, 0, time.UTC)
for _, language := range []string{"zh", "en"} {
rendered, ok := LunarEclipseDetailedSVG(date, LunarEclipseDetailedSVGOptions{
Language: language, Location: time.UTC,
})
if !ok {
t.Fatalf("%s: missing chart", language)
}
shared := []string{
`class="lunar-geocentric-block"`, // 日月地心坐标块
`class="lunar-detailed-panel"`, // 历时/接触/……面板
`class="lunar-scale-bar"`, // 弧分比例尺
`class="lunar-visibility-regions"`, // 可见性区域
`class="entire-eclipse-region"`, // 全程可见区
`<path class="land"`, // 陆地底图
}
// 底图图例按语言取词。
if language == "en" {
shared = append(shared, "Entire eclipse", "Moonrise during eclipse", "Not visible")
} else {
shared = append(shared, "全程可见", "带食月出", "带食月落", "不可见")
}
for _, want := range shared {
if !strings.Contains(rendered, want) {
t.Fatalf("%s: combined chart missing %q", language, want)
}
}
if err := validateEclipseMapXML(rendered); err != nil {
t.Fatalf("%s: chart is not valid XML: %v", language, err)
}
}
}
// 地影几何要与 NASA 月食图逐项吻合:2009 之外的 2025-03-14 全食,Gamma 0.3481、P./U. Radius 1.1899/0.6537。
func TestLunarEclipseShadowGeometryMatchesNASABulletin(t *testing.T) {
date := time.Date(2025, time.March, 14, 0, 0, 0, 0, time.UTC)
result := basic.LunarEclipse(basic.TD2UT(basic.Date2JDE(date), true))
geometry := basic.LunarEclipseShadowGeometryAt(result.Maximum)
t.Logf("gamma=%.4f P.Radius=%.4f U.Radius=%.4f umbral=%.4f penumbral=%.4f",
geometry.Gamma, geometry.PenumbralRadiusDegrees, geometry.UmbralRadiusDegrees,
result.Magnitude, result.PenumbralMagnitude)
if math.Abs(geometry.Gamma-0.3481) > 0.001 {
t.Fatalf("gamma = %.4f, want 0.3481", geometry.Gamma)
}
if math.Abs(geometry.PenumbralRadiusDegrees-1.1899) > 0.001 {
t.Fatalf("penumbral radius = %.4f, want 1.1899", geometry.PenumbralRadiusDegrees)
}
if math.Abs(geometry.UmbralRadiusDegrees-0.6537) > 0.001 {
t.Fatalf("umbral radius = %.4f, want 0.6537", geometry.UmbralRadiusDegrees)
}
if math.Abs(result.Magnitude-1.1784) > 0.001 {
t.Fatalf("umbral magnitude = %.4f, want 1.1784", result.Magnitude)
}
if math.Abs(result.PenumbralMagnitude-2.2595) > 0.001 {
t.Fatalf("penumbral magnitude = %.4f, want 2.2595", result.PenumbralMagnitude)
}
}