feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑 - 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口 - 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界 - 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名 - 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验 - 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口 - 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
This commit is contained in:
@@ -124,3 +124,48 @@ func TestFindPlanetOccultationsValidatesInputs(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindBestPlanetOccultationsKeepsNonCentralEvents(t *testing.T) {
|
||||
// 2025-01-05 月掩海王星与 2025-07-28 月掩火星都是月影轴不与地球椭球相交的非中心
|
||||
// 事件:最佳站心曾取外接触切点,该点位于掩带边缘、落在掩食之外,整场被事件搜索
|
||||
// 丢弃。事件搜索与路径搜索必须报告同一场事件,掩甚站心必须落在掩食之内。
|
||||
// The 2025-01-05 Neptune and 2025-07-28 Mars occultations are non-central events
|
||||
// whose shadow axis misses the ellipsoid. The best station used to be taken at the
|
||||
// outer contact tangent, which sits on the band edge and outside the occultation, so
|
||||
// the whole event was dropped from the search. The event and path searches must
|
||||
// report the same event with a greatest station inside the occultation.
|
||||
tests := []struct {
|
||||
name string
|
||||
planet OccultationPlanet
|
||||
day time.Time
|
||||
}{
|
||||
{name: "2025-01-05 Neptune", planet: OccultationNeptune, day: time.Date(2025, time.January, 5, 0, 0, 0, 0, time.UTC)},
|
||||
{name: "2025-07-28 Mars", planet: OccultationMars, day: time.Date(2025, time.July, 28, 0, 0, 0, 0, time.UTC)},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
start := test.day.Add(-24 * time.Hour)
|
||||
end := test.day.Add(24 * time.Hour)
|
||||
events, err := FindBestPlanetOccultations(start, end, test.planet, OccultationSearchOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("FindBestPlanetOccultations() error = %v", err)
|
||||
}
|
||||
paths, err := FindPlanetOccultationPaths(start, end, test.planet, OccultationPathOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("FindPlanetOccultationPaths() error = %v", err)
|
||||
}
|
||||
if len(events) != 1 || len(paths) != 1 {
|
||||
t.Fatalf("event search returned %d events, path search %d, want one each", len(events), len(paths))
|
||||
}
|
||||
event := events[0]
|
||||
limit := event.MoonSemidiameterArcsec + event.PlanetSemidiameterArcsec
|
||||
if event.MinimumSeparationArcsec > limit {
|
||||
t.Fatalf("greatest station lies outside the occultation: separation=%.3f limit=%.3f",
|
||||
event.MinimumSeparationArcsec, limit)
|
||||
}
|
||||
if delta := math.Abs(event.Greatest.Sub(paths[0].Greatest.Time).Seconds()); delta > 60 {
|
||||
t.Fatalf("greatest differs from the path search by %.1fs", delta)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user