feat: 完善时标与天象几何计算并扩展输出接口

- 新增时标、ΔT 模型、质心时间与 UT1 支持
- 改进日月食、月掩、行星事件及路径边界计算
- 完善恒星三维自行与动态距离传播
- 扩展 SVG、GeoJSON、KML 输出与底层距离换算工具
- 整理中英文手册、示例资源及回归测试
This commit is contained in:
2026-09-23 18:55:12 +08:00
parent 1f31a9b5b5
commit 16c62a97d5
503 changed files with 33290 additions and 9471 deletions
+16 -16
View File
@@ -16,8 +16,8 @@ const (
// DeclinationEvent 赤纬极值事件 / declination extremum event.
type DeclinationEvent struct {
// JDE 是事件发生时刻对应的世界时儒略日 / event time as UTC-based Julian day.
JDE float64
// JD 是事件发生时刻对应的世界时儒略日 / event time as UTC-based Julian day.
JD float64
// Declination 是该时刻月心地心赤纬,单位度 / geocentric lunar declination at the event, in degrees.
Declination float64
}
@@ -124,8 +124,8 @@ func ClosestMoonMaximumSouthDeclination(jd float64) DeclinationEvent {
func moonMaximumDeclinationsInMonth(year int, month time.Month, coeffs moonMaxDeclinationCoefficients) []DeclinationEvent {
startUTC := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
endUTC := startUTC.AddDate(0, 1, 0)
startTT := TD2UT(Date2JDE(startUTC), true)
endTT := TD2UT(Date2JDE(endUTC), true)
startTT := UTC2TT(Date2JD(startUTC))
endTT := UTC2TT(Date2JD(endUTC))
kStart := int(math.Floor((startTT-coeffs.JDE0)/moonMaxDeclinationMeanMonthDays)) - 1
kEnd := int(math.Ceil((endTT-coeffs.JDE0)/moonMaxDeclinationMeanMonthDays)) + 1
@@ -142,7 +142,7 @@ func moonMaximumDeclinationsInMonth(year int, month time.Month, coeffs moonMaxDe
events := make([]DeclinationEvent, 0, 2)
for k := kStart; k <= kEnd; k++ {
event := moonMaximumDeclinationEvent(k, coeffs, cfg)
eventTimeUTC := JDE2DateByZone(event.JDE, time.UTC, false)
eventTimeUTC := JD2DateByZone(event.JD, time.UTC, false)
if eventTimeUTC.Before(startUTC) || !eventTimeUTC.Before(endUTC) {
continue
}
@@ -150,7 +150,7 @@ func moonMaximumDeclinationsInMonth(year int, month time.Month, coeffs moonMaxDe
}
sort.Slice(events, func(i, j int) bool {
return events[i].JDE < events[j].JDE
return events[i].JD < events[j].JD
})
return events
}
@@ -161,7 +161,7 @@ func moonMaximumDeclinationEvent(k int, coeffs moonMaxDeclinationCoefficients, c
return HMoonTrueDecN(sampleTT, -1)
})
return DeclinationEvent{
JDE: TD2UT(eventTT, false),
JD: TT2UTC(eventTT),
Declination: declination,
}
}
@@ -180,10 +180,10 @@ func moonMaximumDeclinationSearch(jd float64, coeffs moonMaxDeclinationCoefficie
event := moonMaximumDeclinationEvent(centerK, coeffs, cfg)
// 事件时刻随周期序号单调递增:该方向上最近的候选就是 centerK 沿该方向第一个满足方向不变量
// 的周期;命中后只需再回退检查更早的周期是否同样满足,可达范围仍旧是 ±3 个周期。
if !moonMaximumDeclinationMatchesDirection(event.JDE-jd, direction, includeCurrent) {
if !moonMaximumDeclinationMatchesDirection(event.JD-jd, direction, includeCurrent) {
for offset := 1; offset <= moonMaxDeclinationSearchSpan; offset++ {
event = moonMaximumDeclinationEvent(centerK+step*offset, coeffs, cfg)
if moonMaximumDeclinationMatchesDirection(event.JDE-jd, direction, includeCurrent) {
if moonMaximumDeclinationMatchesDirection(event.JD-jd, direction, includeCurrent) {
return event
}
}
@@ -191,7 +191,7 @@ func moonMaximumDeclinationSearch(jd float64, coeffs moonMaxDeclinationCoefficie
}
for offset := 1; offset <= moonMaxDeclinationSearchSpan; offset++ {
previous := moonMaximumDeclinationEvent(centerK-step*offset, coeffs, cfg)
if !moonMaximumDeclinationMatchesDirection(previous.JDE-jd, direction, includeCurrent) {
if !moonMaximumDeclinationMatchesDirection(previous.JD-jd, direction, includeCurrent) {
break
}
event = previous
@@ -207,15 +207,15 @@ func moonClosestMaximumDeclination(jd float64, coeffs moonMaxDeclinationCoeffici
centerK := moonMaximumDeclinationOffset(jd, coeffs)
center := moonMaximumDeclinationEvent(centerK, coeffs, cfg)
var last, next DeclinationEvent
if center.JDE <= jd {
if center.JD <= jd {
last = center
next = moonMaximumDeclinationAround(jd, coeffs, cfg, centerK, 1, false)
} else {
next = center
last = moonMaximumDeclinationAround(jd, coeffs, cfg, centerK, -1, true)
}
lastDistance := math.Abs(jd - last.JDE)
nextDistance := math.Abs(next.JDE - jd)
lastDistance := math.Abs(jd - last.JD)
nextDistance := math.Abs(next.JD - jd)
if lastDistance <= nextDistance {
return last
}
@@ -231,7 +231,7 @@ func moonMaximumDeclinationAround(jd float64, coeffs moonMaxDeclinationCoefficie
}
for offset := 1; offset <= moonMaxDeclinationSearchSpan; offset++ {
event := moonMaximumDeclinationEvent(centerK+step*offset, coeffs, cfg)
if moonMaximumDeclinationMatchesDirection(event.JDE-jd, direction, includeCurrent) {
if moonMaximumDeclinationMatchesDirection(event.JD-jd, direction, includeCurrent) {
return event
}
}
@@ -251,7 +251,7 @@ func moonMaximumDeclinationSearchConfig(coeffs moonMaxDeclinationCoefficients) a
// moonMaximumDeclinationOffset 查询时刻落在哪个平均周期(种子多项式的中心序号)。
func moonMaximumDeclinationOffset(jd float64, coeffs moonMaxDeclinationCoefficients) int {
return int(math.Round((TD2UT(jd, true) - coeffs.JDE0) / moonMaxDeclinationMeanMonthDays))
return int(math.Round((UTC2TT(jd) - coeffs.JDE0) / moonMaxDeclinationMeanMonthDays))
}
func moonMaximumDeclinationMatchesDirection(delta float64, direction int, includeCurrent bool) bool {
@@ -272,7 +272,7 @@ func moonMaximumDeclinationMatchesDirection(delta float64, direction int, includ
}
func moonMaximumDeclinationEarlier(a, b DeclinationEvent) bool {
return a.JDE < b.JDE
return a.JD < b.JD
}
func moonMaximumDeclinationSeedTT(k int, coeffs moonMaxDeclinationCoefficients) float64 {