fix: 修复天象事件 API 在事件边界附近的重复返回问题

- 修正合月、合日、留等Last/Next/Closest接口在精确命中和事件后秒级查询时仍返回当前事件的问题,避免应用侧枚举卡死
- 收紧事件边界判定,并补强水星、金星、火星近事件路径的稳定化,保证公开API的单调前进语义
- 补充公开wrapper、跨世纪样本和外部基线回归,覆盖合月邻近事件与边界场景
This commit is contained in:
2026-05-23 23:08:05 +08:00
parent be3af3884c
commit 46b555cd49
10 changed files with 235 additions and 51 deletions
+13 -25
View File
@@ -202,10 +202,14 @@ func venusConjunction(jde float64, next uint8) float64 {
}
left := queryTT
leftVal := venusSunLongitudeDeltaN(left, venusEventSearchN)
if math.Abs(leftVal) <= 30.0/86400.0 {
if math.Abs(venusSunLongitudeDelta(queryTT)) <= 30.0/86400.0 {
exact := eventZeroRefine(left, 1.0, 0.000005, venusSunLongitudeDelta)
if math.Abs(exact-queryTT) <= 1.0 {
return TD2UT(exact, false)
eventUT := TD2UT(exact, false)
if next == 0 && eventUTQueryBeforeOrEqual(eventUT, queryTT) {
return eventUT
}
if next == 1 && eventUTQueryAfterOrEqual(eventUT, queryTT) {
return eventUT
}
}
const step = 8.0
@@ -432,12 +436,12 @@ func venusGreatestElongationInWindow(start, end float64) float64 {
func venusEastElongationWindowEndingAt(inferior float64) (float64, float64) {
lastSuperior := LastVenusSuperiorConjunction(eventUTLastQueryTT(inferior))
return lastSuperior + innerEventEpsilon, inferior - innerEventEpsilon
return lastSuperior + innerEventWindowPadding, inferior - innerEventWindowPadding
}
func venusWestElongationWindowEndingAt(superior float64) (float64, float64) {
lastInferior := LastVenusInferiorConjunction(eventUTLastQueryTT(superior))
return lastInferior + innerEventEpsilon, superior - innerEventEpsilon
return lastInferior + innerEventWindowPadding, superior - innerEventWindowPadding
}
func venusEastElongationWindowContaining(jde float64) (float64, float64) {
@@ -539,35 +543,19 @@ func LastVenusGreatestElongation(jde float64) float64 {
}
func LastVenusInferiorConjunctionInclusive(jde float64) float64 {
date := LastVenusConjunction(jde)
if venusConjunctionTypeAt(date) {
return date
}
return LastVenusConjunction(eventUTLastQueryTT(date))
return inclusiveLastSimpleEvent(jde, LastVenusInferiorConjunction, NextVenusInferiorConjunction)
}
func NextVenusInferiorConjunctionInclusive(jde float64) float64 {
date := NextVenusConjunction(jde)
if venusConjunctionTypeAt(date) {
return date
}
return NextVenusConjunction(eventUTNextQueryTT(date))
return inclusiveNextSimpleEvent(jde, LastVenusInferiorConjunction, NextVenusInferiorConjunction)
}
func LastVenusSuperiorConjunctionInclusive(jde float64) float64 {
date := LastVenusConjunction(jde)
if !venusConjunctionTypeAt(date) {
return date
}
return LastVenusConjunction(eventUTLastQueryTT(date))
return inclusiveLastSimpleEvent(jde, LastVenusSuperiorConjunction, NextVenusSuperiorConjunction)
}
func NextVenusSuperiorConjunctionInclusive(jde float64) float64 {
date := NextVenusConjunction(jde)
if !venusConjunctionTypeAt(date) {
return date
}
return NextVenusConjunction(eventUTNextQueryTT(date))
return inclusiveNextSimpleEvent(jde, LastVenusSuperiorConjunction, NextVenusSuperiorConjunction)
}
func LastVenusRetrogradeInclusive(jde float64) float64 {