2026-05-01 22:38:44 +08:00
package basic
import (
"math"
. "b612.me/astro/tools"
)
const (
VENUS_S_PERIOD = 1 / (( 1 / 224.701 ) - ( 1 / 365.256363004 ))
venusEventSearchN = 16
2026-10-15 23:54:15 +08:00
// venusConjunctionSameInstantDegrees 「同刻」快速路径的视黄经差触发阈值(度):必须明显大于
// 截断级数与全项级数的最大视黄经差,否则「查询落在合前几秒」时起点符号相反,方向扫描会跨过这次合。
// 0.05 度约合 38 分钟;侧向判定仍用 0.1 秒口径,语义不变。
2026-09-17 12:27:40 +08:00
venusConjunctionSameInstantDegrees = 5.0e-2
2026-05-01 22:38:44 +08:00
)
2026-10-15 23:54:15 +08:00
func venusSunLongitudeDelta ( jde float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
sub := Limit360 ( VenusApparentLoWithInstance ( jde , inst ) - HSunApparentLoWithInstance ( jde , inst ))
2026-05-01 22:38:44 +08:00
if sub > 180 {
sub -= 360
}
if sub < - 180 {
sub += 360
}
return sub
}
2026-10-15 23:54:15 +08:00
func venusSunLongitudeDeltaN ( jde float64 , n int , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
sub := Limit360 ( VenusApparentLoNWithInstance ( jde , n , inst ) - HSunApparentLoNWithInstance ( jde , n , inst ))
2026-05-01 22:38:44 +08:00
if sub > 180 {
sub -= 360
}
if sub < - 180 {
sub += 360
}
return sub
}
2026-10-15 23:54:15 +08:00
func venusRADerivative ( jde , val float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
sub := VenusApparentRaWithInstance ( jde + val , inst ) - VenusApparentRaWithInstance ( jde - val , inst )
2026-05-01 22:38:44 +08:00
if sub > 180 {
sub -= 360
}
if sub < - 180 {
sub += 360
}
return sub / ( 2 * val )
}
2026-10-15 23:54:15 +08:00
func venusRAContinuousForMax ( jde float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
ra := VenusApparentRaWithInstance ( jde , inst )
2026-05-22 12:24:41 +08:00
if ra < 180 {
return ra + 360
}
return ra
}
2026-10-15 23:54:15 +08:00
func venusRAContinuousForMaxN ( jde float64 , n int , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
ra := VenusApparentRaNWithInstance ( jde , n , inst )
2026-05-22 12:24:41 +08:00
if ra < 180 {
return ra + 360
}
return ra
}
2026-10-15 23:54:15 +08:00
func venusRAContinuousForMin ( jde float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
ra := VenusApparentRaWithInstance ( jde , inst )
2026-05-22 12:24:41 +08:00
if ra > 180 {
return ra - 360
}
return ra
}
2026-10-15 23:54:15 +08:00
func venusRAContinuousForMinN ( jde float64 , n int , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
ra := VenusApparentRaNWithInstance ( jde , n , inst )
2026-05-22 12:24:41 +08:00
if ra > 180 {
return ra - 360
}
return ra
}
func venusRAExtremumRefine ( seed , start , end , step float64 , fn func ( float64 ) float64 ) float64 {
centerJD := clampFloat64 ( seed , start , end )
halfStep := step
bestJD := centerJD
bestVal := fn ( centerJD )
for i := 0 ; i < 8 ; i ++ {
leftJD := clampFloat64 ( centerJD - halfStep , start , end )
rightJD := clampFloat64 ( centerJD + halfStep , start , end )
leftVal := fn ( leftJD )
centerVal := fn ( centerJD )
rightVal := fn ( rightJD )
if leftVal > bestVal {
bestVal = leftVal
bestJD = leftJD
}
if centerVal > bestVal {
bestVal = centerVal
bestJD = centerJD
}
if rightVal > bestVal {
bestVal = rightVal
bestJD = rightJD
}
denominator := leftVal - 2 * centerVal + rightVal
if denominator == 0 {
centerJD = bestJD
halfStep /= 2
continue
}
vertexJD := centerJD + 0.5 * halfStep * ( leftVal - rightVal ) / denominator
vertexJD = clampFloat64 ( vertexJD , leftJD , rightJD )
vertexVal := fn ( vertexJD )
if vertexVal > bestVal {
bestVal = vertexVal
bestJD = vertexJD
}
centerJD = bestJD
halfStep /= 2
}
return bestJD
}
2026-10-15 23:54:15 +08:00
func venusSunElongationN ( jde float64 , n int , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
lo1 , bo1 := VenusApparentLoBoNWithInstance ( jde , n , inst )
lo2 := HSunApparentLoNWithInstance ( jde , n , inst )
bo2 := HSunTrueBoNWithInstance ( jde , n , inst )
2026-05-01 22:38:44 +08:00
return StarAngularSeparation ( lo1 , bo1 , lo2 , bo2 )
}
2026-10-15 23:54:15 +08:00
func venusConjunction ( jde float64 , next uint8 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( jde ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
queryTT := jde
direction := - 1.0
if next == 1 {
direction = 1
}
left := queryTT
2026-10-15 23:54:15 +08:00
leftVal := venusSunLongitudeDeltaN ( left , venusEventSearchN , inst )
if math . Abs ( venusSunLongitudeDelta ( queryTT , inst )) <= venusConjunctionSameInstantDegrees {
if exact , ok := venusConjunctionRefine ( left , 1.0 , inst ); ok {
2026-09-23 18:55:12 +08:00
eventUT := TT2UTC ( exact )
2026-08-06 12:00:56 +08:00
if next == 0 && eventUTQueryBeforeOrEqual ( eventUT , queryTT ) {
return eventUT
}
if next == 1 && eventUTQueryAfterOrEqual ( eventUT , queryTT ) {
return eventUT
}
2026-05-01 22:38:44 +08:00
}
}
2026-05-22 12:24:41 +08:00
const step = 8.0
for i := 0 ; i < 80 ; i ++ {
right := queryTT + direction * step * float64 ( i + 1 )
2026-10-15 23:54:15 +08:00
rightVal := venusSunLongitudeDeltaN ( right , venusEventSearchN , inst )
2026-05-22 12:24:41 +08:00
if leftVal == 0 || rightVal == 0 || leftVal * rightVal <= 0 {
center := ( left + right ) / 2.0
halfWindow := math . Abs ( right - left ) / 2.0
2026-10-15 23:54:15 +08:00
if exact , ok := venusConjunctionRefine ( center , halfWindow , inst ); ok {
2026-09-23 18:55:12 +08:00
return TT2UTC ( exact )
2026-08-06 12:00:56 +08:00
}
2026-09-17 12:27:40 +08:00
// 截断级数在根附近的符号可能与全项不一致(查询几乎正好落在合上),
// 此时改用全项级数做方向扫描兜底,而不是直接有界失败。
2026-10-15 23:54:15 +08:00
return venusConjunctionFullDirectionalScan ( queryTT , direction , inst )
2026-05-01 22:38:44 +08:00
}
2026-05-22 12:24:41 +08:00
left = right
leftVal = rightVal
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
// 640 天已经覆盖一个金星会合周期;仍无括号通常表示输入超出解析项的可靠范围。
// 继续按 5 微日扫描整个周期会产生数亿次星历计算,因此在这里有界失败。
// The 640-day directional scan already exceeds one Venus synodic period. If it
// still finds no bracket, fail in a bounded way instead of scanning hundreds
// of millions of five-microday samples across the full fallback window.
return math . NaN ()
}
2026-09-17 12:27:40 +08:00
// venusConjunctionFullDirectionalScan 全项级数的方向扫描(截断括号未被确认时的兜底)。
2026-10-15 23:54:15 +08:00
func venusConjunctionFullDirectionalScan ( queryTT , direction float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
2026-09-17 12:27:40 +08:00
const (
step = 8.0
maxSteps = 80
)
left := queryTT
2026-10-15 23:54:15 +08:00
leftVal := venusSunLongitudeDelta ( left , inst )
2026-09-17 12:27:40 +08:00
if ! isFiniteFloat ( leftVal ) {
return math . NaN ()
}
for i := 0 ; i < maxSteps ; i ++ {
right := queryTT + direction * step * float64 ( i + 1 )
2026-10-15 23:54:15 +08:00
rightVal := venusSunLongitudeDelta ( right , inst )
2026-09-17 12:27:40 +08:00
if ! isFiniteFloat ( rightVal ) {
return math . NaN ()
}
if leftVal == 0 || rightVal == 0 || leftVal * rightVal < 0 {
center := ( left + right ) / 2.0
2026-10-15 23:54:15 +08:00
if exact , ok := venusConjunctionRefine ( center , math . Abs ( right - left ) / 2.0 , inst ); ok {
2026-09-23 18:55:12 +08:00
return TT2UTC ( exact )
2026-09-17 12:27:40 +08:00
}
return math . NaN ()
}
left = right
leftVal = rightVal
}
return math . NaN ()
}
2026-10-15 23:54:15 +08:00
func venusConjunctionRefine ( seed , halfWindow float64 , instances ...* Instance ) ( float64 , bool ) {
inst := instanceValue ( instances )
2026-09-23 18:55:12 +08:00
leftJDE := seed - halfWindow
centerJDE := seed
rightJDE := seed + halfWindow
2026-10-15 23:54:15 +08:00
leftVal := venusSunLongitudeDelta ( leftJDE , inst )
centerVal := venusSunLongitudeDelta ( centerJDE , inst )
rightVal := venusSunLongitudeDelta ( rightJDE , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( leftVal ) || ! isFiniteFloat ( centerVal ) || ! isFiniteFloat ( rightVal ) {
return math . NaN (), false
}
2026-09-23 18:55:12 +08:00
if _ , _ , _ , _ , ok := eventZeroBracket ( leftJDE , leftVal , centerJDE , centerVal , rightJDE , rightVal ); ! ok {
2026-08-06 12:00:56 +08:00
return math . NaN (), false
}
2026-10-15 23:54:15 +08:00
return eventZeroRefine ( seed , halfWindow , 0.000005 , func ( jde float64 ) float64 { return venusSunLongitudeDelta ( jde , inst ) }), true
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func venusConjunctionTypeAt ( eventUT float64 , instances ...* Instance ) bool {
inst := instanceValue ( instances )
return EarthVenusAwayWithInstance ( eventUT , inst ) <= EarthAwayWithInstance ( eventUT , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func nextVenusTypedConjunctionFromEvent ( jde float64 , inferior bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
date := NextVenusConjunctionStrictWithInstance ( jde , inst )
if venusConjunctionTypeAt ( date , inst ) == inferior {
2026-05-22 12:24:41 +08:00
return date
}
2026-10-15 23:54:15 +08:00
return NextVenusConjunctionStrictWithInstance ( eventUTNextQueryTT ( date ), inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func lastVenusTypedConjunctionFromEvent ( jde float64 , inferior bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
date := LastVenusConjunctionStrictWithInstance ( jde , inst )
if venusConjunctionTypeAt ( date , inst ) == inferior {
2026-05-22 12:24:41 +08:00
return date
}
2026-10-15 23:54:15 +08:00
return LastVenusConjunctionStrictWithInstance ( eventUTLastQueryTT ( date ), inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusConjunctionWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusConjunctionWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusConjunctionStrictWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusConjunctionStrictWithInstance ( jde , inst ) })
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusConjunctionWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusConjunctionWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusConjunctionStrictWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusConjunctionStrictWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusConjunctionStrictWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusConjunctionStrictWithInstance ( jde float64 , inst * Instance ) float64 {
return venusConjunction ( jde , 0 , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusConjunctionStrictWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusConjunctionStrictWithInstance ( jde float64 , inst * Instance ) float64 {
return venusConjunction ( jde , 1 , inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
func nextVenusTypedConjunction ( jde float64 , inferior bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
return nextVenusTypedConjunctionFromEvent ( jde , inferior , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func lastVenusTypedConjunction ( jde float64 , inferior bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
return lastVenusTypedConjunctionFromEvent ( jde , inferior , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusInferiorConjunctionWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusInferiorConjunctionWithInstance ( jde float64 , inst * Instance ) float64 {
return nextVenusTypedConjunction ( jde , true , inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusSuperiorConjunctionWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusSuperiorConjunctionWithInstance ( jde float64 , inst * Instance ) float64 {
return nextVenusTypedConjunction ( jde , false , inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusInferiorConjunctionWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusInferiorConjunctionWithInstance ( jde float64 , inst * Instance ) float64 {
return lastVenusTypedConjunction ( jde , true , inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusSuperiorConjunctionWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusSuperiorConjunctionWithInstance ( jde float64 , inst * Instance ) float64 {
return lastVenusTypedConjunction ( jde , false , inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusRetrogradeWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusRetrogradeWithInstance ( jde float64 , inst * Instance ) float64 {
p2r := NextVenusProgradeToRetrogradeWithInstance ( jde , inst )
r2p := NextVenusRetrogradeToProgradeWithInstance ( jde , inst )
2026-05-22 12:24:41 +08:00
if sameEventJD ( p2r , r2p ) {
return p2r
2026-05-01 22:38:44 +08:00
}
2026-09-17 12:27:40 +08:00
return earliestFiniteEventUT ( p2r , r2p )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusRetrogradeWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusRetrogradeWithInstance ( jde float64 , inst * Instance ) float64 {
p2r := LastVenusProgradeToRetrogradeWithInstance ( jde , inst )
r2p := LastVenusRetrogradeToProgradeWithInstance ( jde , inst )
2026-05-22 12:24:41 +08:00
if sameEventJD ( p2r , r2p ) {
return p2r
}
2026-09-17 12:27:40 +08:00
return latestFiniteEventUT ( p2r , r2p )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func venusStationInWindow ( start , end float64 , progradeToRetrograde bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
2026-05-22 12:24:41 +08:00
var best float64
if progradeToRetrograde {
guess := scanWindowForMax ( start , end , 2.0 , func ( jd float64 ) float64 {
2026-10-15 23:54:15 +08:00
return venusRAContinuousForMaxN ( jd , venusEventSearchN , inst )
2026-05-22 12:24:41 +08:00
})
best = venusRAExtremumRefine ( guess , start , end , 1.0 , func ( jd float64 ) float64 {
2026-10-15 23:54:15 +08:00
return venusRAContinuousForMax ( jd , inst )
2026-05-22 12:24:41 +08:00
})
} else {
guess := scanWindowForMax ( start , end , 2.0 , func ( jd float64 ) float64 {
2026-10-15 23:54:15 +08:00
return - venusRAContinuousForMinN ( jd , venusEventSearchN , inst )
2026-05-22 12:24:41 +08:00
})
best = venusRAExtremumRefine ( guess , start , end , 1.0 , func ( jd float64 ) float64 {
2026-10-15 23:54:15 +08:00
return - venusRAContinuousForMin ( jd , inst )
2026-05-22 12:24:41 +08:00
})
}
2026-10-15 23:54:15 +08:00
// 抛物顶点法仍有秒级残差,会让「查询落在站前 1 秒」这类边界查询跳到下一个会合周期;
// 这里再用 RA 变化率的零点做一次割线抛光,把站时刻精度压到亚秒级,
// 抛光失败(括号内无异号)时保留顶点法结果。
if polished , ok := venusStationPolish ( best , progradeToRetrograde , inst ); ok {
2026-09-17 12:27:40 +08:00
best = polished
}
2026-09-23 18:55:12 +08:00
return TT2UTC ( best )
2026-05-22 12:24:41 +08:00
}
2026-09-17 12:27:40 +08:00
// venusStationPolish 在抛物顶点结果附近求 RA 变化率的零点。
// progradeToRetrograde=true 时 RA 变化率由正转负(极大值),否则由负转正(极小值)。
2026-10-15 23:54:15 +08:00
func venusStationPolish ( seed float64 , progradeToRetrograde bool , instances ...* Instance ) ( float64 , bool ) {
inst := instanceValue ( instances )
rate := func ( jd float64 ) float64 { return venusRADerivative ( jd , stationDerivativeStepDay , inst ) }
2026-09-17 12:27:40 +08:00
for _ , halfWindow := range [] float64 { 120.0 / 86400.0 , 600.0 / 86400.0 } {
leftJD := seed - halfWindow
rightJD := seed + halfWindow
leftValue := rate ( leftJD )
rightValue := rate ( rightJD )
if ! isFiniteFloat ( leftValue ) || ! isFiniteFloat ( rightValue ) {
return math . NaN (), false
}
if leftValue == 0 {
return leftJD , true
}
if rightValue == 0 {
return rightJD , true
}
if leftValue * rightValue > 0 {
continue
}
if progradeToRetrograde != ( leftValue > 0 ) {
return math . NaN (), false
}
root , ok := eventBracketSecantRoot ( leftJD , rightJD , leftValue , rightValue , 0.01 / 86400.0 , rate )
if ! ok {
return math . NaN (), false
}
return root , true
}
return math . NaN (), false
}
2026-10-15 23:54:15 +08:00
func venusProgradeToRetrogradeAroundInferior ( inferior float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
return venusStationInWindow ( inferior - 30.0 , inferior - 14.0 , true , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func venusRetrogradeToProgradeAroundInferior ( inferior float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
return venusStationInWindow ( inferior + 14.0 , inferior + 24.0 , false , inst )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusProgradeToRetrogradeWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusProgradeToRetrogradeWithInstance ( jde float64 , inst * Instance ) float64 {
inferior := NextVenusInferiorConjunctionWithInstance ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusProgradeToRetrogradeAroundInferior ( inferior , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-09-17 12:27:40 +08:00
if stationUTQueryAfterOrEqual ( date , jde ) {
2026-05-22 12:24:41 +08:00
return date
}
2026-10-15 23:54:15 +08:00
inferior = NextVenusInferiorConjunctionWithInstance ( eventUTNextQueryTT ( inferior ), inst )
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusRetrogradeToProgradeWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusRetrogradeToProgradeWithInstance ( jde float64 , inst * Instance ) float64 {
inferior := LastVenusInferiorConjunctionWithInstance ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusRetrogradeToProgradeAroundInferior ( inferior , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-09-17 12:27:40 +08:00
if stationUTQueryAfterOrEqual ( date , jde ) {
2026-05-22 12:24:41 +08:00
return date
}
2026-10-15 23:54:15 +08:00
inferior = NextVenusInferiorConjunctionWithInstance ( eventUTNextQueryTT ( inferior ), inst )
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusProgradeToRetrogradeWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusProgradeToRetrogradeWithInstance ( jde float64 , inst * Instance ) float64 {
inferior := NextVenusInferiorConjunctionWithInstance ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusProgradeToRetrogradeAroundInferior ( inferior , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-09-17 12:27:40 +08:00
if stationUTQueryBeforeOrEqual ( date , jde ) {
2026-05-22 12:24:41 +08:00
return date
}
2026-10-15 23:54:15 +08:00
inferior = LastVenusInferiorConjunctionWithInstance ( eventUTLastQueryTT ( inferior ), inst )
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusRetrogradeToProgradeWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusRetrogradeToProgradeWithInstance ( jde float64 , inst * Instance ) float64 {
inferior := LastVenusInferiorConjunctionWithInstance ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusRetrogradeToProgradeAroundInferior ( inferior , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-09-17 12:27:40 +08:00
if stationUTQueryBeforeOrEqual ( date , jde ) {
2026-05-22 12:24:41 +08:00
return date
}
2026-10-15 23:54:15 +08:00
inferior = LastVenusInferiorConjunctionWithInstance ( eventUTLastQueryTT ( inferior ), inst )
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// VenusSunElongationWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func VenusSunElongationWithInstance ( jde float64 , inst * Instance ) float64 {
lo1 , bo1 := VenusApparentLoBoWithInstance ( jde , inst )
lo2 := HSunApparentLoWithInstance ( jde , inst )
bo2 := HSunTrueBoWithInstance ( jde , inst )
2026-05-01 22:38:44 +08:00
return StarAngularSeparation ( lo1 , bo1 , lo2 , bo2 )
}
2026-09-17 12:27:40 +08:00
// venusGreatestElongationInWindow 求窗口内大距:目标是公开 VenusSunElongation 的极大(视距角),
// 而不是忽略光行差/视位置修正的真距角,否则返回的时刻不是调用方能量到的那个极值。
// 窗口两端是世界时,目标函数收力学时,因此逐次换算。
2026-10-15 23:54:15 +08:00
func venusGreatestElongationInWindow ( start , end float64 , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
2026-09-17 12:27:40 +08:00
return maximizeInWindow ( start , end , 5.0 , func ( utJD float64 ) float64 {
2026-10-15 23:54:15 +08:00
return venusSunElongationN ( UTC2TT ( utJD ), venusEventSearchN , inst )
2026-09-17 12:27:40 +08:00
}, func ( utJD float64 ) float64 {
2026-10-15 23:54:15 +08:00
return VenusSunElongationWithInstance ( UTC2TT ( utJD ), inst )
2026-05-22 12:24:41 +08:00
})
}
2026-10-15 23:54:15 +08:00
func venusEastElongationWindowEndingAt ( inferior float64 , instances ...* Instance ) ( float64 , float64 ) {
inst := instanceValue ( instances )
lastSuperior := LastVenusSuperiorConjunctionWithInstance ( eventUTLastQueryTT ( inferior ), inst )
2026-05-23 23:08:05 +08:00
return lastSuperior + innerEventWindowPadding , inferior - innerEventWindowPadding
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func venusWestElongationWindowEndingAt ( superior float64 , instances ...* Instance ) ( float64 , float64 ) {
inst := instanceValue ( instances )
lastInferior := LastVenusInferiorConjunctionWithInstance ( eventUTLastQueryTT ( superior ), inst )
2026-05-23 23:08:05 +08:00
return lastInferior + innerEventWindowPadding , superior - innerEventWindowPadding
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func venusEastElongationWindowContaining ( jde float64 , instances ...* Instance ) ( float64 , float64 ) {
inst := instanceValue ( instances )
nextInferior := NextVenusInferiorConjunctionWithInstance ( jde , inst )
start , end := venusEastElongationWindowEndingAt ( nextInferior , inst )
2026-05-22 12:24:41 +08:00
if eventUTQueryBeforeOrEqual ( start , jde ) && eventUTQueryAfterOrEqual ( end , jde ) {
return start , end
}
2026-10-15 23:54:15 +08:00
currentInferior := LastVenusInferiorConjunctionWithInstance ( jde , inst )
return venusEastElongationWindowEndingAt ( currentInferior , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func venusWestElongationWindowContaining ( jde float64 , instances ...* Instance ) ( float64 , float64 ) {
inst := instanceValue ( instances )
nextSuperior := NextVenusSuperiorConjunctionWithInstance ( jde , inst )
start , end := venusWestElongationWindowEndingAt ( nextSuperior , inst )
2026-05-22 12:24:41 +08:00
if eventUTQueryBeforeOrEqual ( start , jde ) && eventUTQueryAfterOrEqual ( end , jde ) {
return start , end
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
currentSuperior := LastVenusSuperiorConjunctionWithInstance ( jde , inst )
return venusWestElongationWindowEndingAt ( currentSuperior , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func nextVenusGreatestElongationTyped ( jde float64 , east bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( jde ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
if east {
2026-10-15 23:54:15 +08:00
start , windowEnd := venusEastElongationWindowContaining ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusGreatestElongationInWindow ( start , windowEnd , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
if eventUTQueryAfterOrEqual ( date , jde ) {
return date
}
2026-10-15 23:54:15 +08:00
nextInferior := NextVenusInferiorConjunctionWithInstance ( eventUTNextQueryTT ( windowEnd ), inst )
start , windowEnd = venusEastElongationWindowEndingAt ( nextInferior , inst )
2026-05-22 12:24:41 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
start , windowEnd := venusWestElongationWindowContaining ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusGreatestElongationInWindow ( start , windowEnd , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
if eventUTQueryAfterOrEqual ( date , jde ) {
return date
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
nextSuperior := NextVenusSuperiorConjunctionWithInstance ( eventUTNextQueryTT ( windowEnd ), inst )
start , windowEnd = venusWestElongationWindowEndingAt ( nextSuperior , inst )
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
func lastVenusGreatestElongationTyped ( jde float64 , east bool , instances ...* Instance ) float64 {
inst := instanceValue ( instances )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( jde ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
if east {
2026-10-15 23:54:15 +08:00
start , windowEnd := venusEastElongationWindowContaining ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusGreatestElongationInWindow ( start , windowEnd , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
if eventUTQueryBeforeOrEqual ( date , jde ) {
return date
}
2026-10-15 23:54:15 +08:00
prevInferior := LastVenusInferiorConjunctionWithInstance ( eventUTLastQueryTT ( start ), inst )
start , windowEnd = venusEastElongationWindowEndingAt ( prevInferior , inst )
2026-05-22 12:24:41 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
start , windowEnd := venusWestElongationWindowContaining ( jde , inst )
2026-08-06 12:00:56 +08:00
for i := 0 ; i < eventDirectionalSearchIterations ; i ++ {
2026-10-15 23:54:15 +08:00
date := venusGreatestElongationInWindow ( start , windowEnd , inst )
2026-08-06 12:00:56 +08:00
if ! isFiniteFloat ( date ) {
return math . NaN ()
}
2026-05-22 12:24:41 +08:00
if eventUTQueryBeforeOrEqual ( date , jde ) {
return date
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
prevSuperior := LastVenusSuperiorConjunctionWithInstance ( eventUTLastQueryTT ( start ), inst )
start , windowEnd = venusWestElongationWindowEndingAt ( prevSuperior , inst )
2026-05-01 22:38:44 +08:00
}
2026-08-06 12:00:56 +08:00
return math . NaN ()
2026-05-22 12:24:41 +08:00
}
2026-09-17 12:27:40 +08:00
// venusElongationWindowAt 返回包含 jde 的该侧大距窗口;查询落在合的 4 秒内边距里时两侧都不包含。
2026-10-15 23:54:15 +08:00
func venusElongationWindowAt ( jde float64 , east bool , instances ...* Instance ) ( float64 , float64 , bool ) {
inst := instanceValue ( instances )
2026-05-22 12:24:41 +08:00
if east {
2026-10-15 23:54:15 +08:00
start , end := venusEastElongationWindowEndingAt ( NextVenusInferiorConjunctionWithInstance ( jde , inst ), inst )
2026-09-17 12:27:40 +08:00
return start , end , eventUTQueryBeforeOrEqual ( start , jde ) && eventUTQueryAfterOrEqual ( end , jde )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
start , end := venusWestElongationWindowEndingAt ( NextVenusSuperiorConjunctionWithInstance ( jde , inst ), inst )
2026-09-17 12:27:40 +08:00
return start , end , eventUTQueryBeforeOrEqual ( start , jde ) && eventUTQueryAfterOrEqual ( end , jde )
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusGreatestElongationWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusGreatestElongationWithInstance ( jde float64 , inst * Instance ) float64 {
2026-09-17 12:27:40 +08:00
if ! isFiniteFloat ( jde ) {
return math . NaN ()
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// 先只看查询所在一侧的窗口,未过即答案,已过则取另一侧的下一个;赤经差在合附近会提前变号,不能用来定窗口。
2026-09-17 12:27:40 +08:00
for _ , east := range [ 2 ] bool { true , false } {
2026-10-15 23:54:15 +08:00
start , end , ok := venusElongationWindowAt ( jde , east , inst )
2026-09-17 12:27:40 +08:00
if ! ok {
continue
}
2026-10-15 23:54:15 +08:00
if date := venusGreatestElongationInWindow ( start , end , inst ); isFiniteFloat ( date ) && eventUTQueryAfterOrEqual ( date , jde ) {
2026-09-17 12:27:40 +08:00
return date
}
2026-10-15 23:54:15 +08:00
if date := nextVenusGreatestElongationTyped ( jde , ! east , inst ); isFiniteFloat ( date ) && eventUTQueryAfterOrEqual ( date , jde ) {
2026-09-17 12:27:40 +08:00
return date
}
break
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
return earliestFiniteEventUT ( nextVenusGreatestElongationTyped ( jde , true , inst ), nextVenusGreatestElongationTyped ( jde , false , inst ))
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusGreatestElongationWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusGreatestElongationWithInstance ( jde float64 , inst * Instance ) float64 {
2026-09-17 12:27:40 +08:00
if ! isFiniteFloat ( jde ) {
return math . NaN ()
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// 先只看查询所在一侧的窗口,未过即答案,已过则取另一侧的下一个;赤经差在合附近会提前变号,不能用来定窗口。
2026-09-17 12:27:40 +08:00
for _ , east := range [ 2 ] bool { true , false } {
2026-10-15 23:54:15 +08:00
start , end , ok := venusElongationWindowAt ( jde , east , inst )
2026-09-17 12:27:40 +08:00
if ! ok {
continue
}
2026-10-15 23:54:15 +08:00
if date := venusGreatestElongationInWindow ( start , end , inst ); isFiniteFloat ( date ) && eventUTQueryBeforeOrEqual ( date , jde ) {
2026-09-17 12:27:40 +08:00
return date
}
2026-10-15 23:54:15 +08:00
if date := lastVenusGreatestElongationTyped ( jde , ! east , inst ); isFiniteFloat ( date ) && eventUTQueryBeforeOrEqual ( date , jde ) {
2026-09-17 12:27:40 +08:00
return date
}
break
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
return latestFiniteEventUT ( lastVenusGreatestElongationTyped ( jde , true , inst ), lastVenusGreatestElongationTyped ( jde , false , inst ))
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusInferiorConjunctionInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusInferiorConjunctionInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusInferiorConjunctionWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusInferiorConjunctionWithInstance ( jde , inst ) })
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusInferiorConjunctionInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusInferiorConjunctionInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusInferiorConjunctionWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusInferiorConjunctionWithInstance ( jde , inst ) })
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusSuperiorConjunctionInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusSuperiorConjunctionInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusSuperiorConjunctionWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusSuperiorConjunctionWithInstance ( jde , inst ) })
2026-05-01 22:38:44 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusSuperiorConjunctionInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusSuperiorConjunctionInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusSuperiorConjunctionWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusSuperiorConjunctionWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusRetrogradeInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusRetrogradeInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusRetrogradeWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusRetrogradeWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusRetrogradeInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusRetrogradeInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusRetrogradeWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusRetrogradeWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusProgradeToRetrogradeInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusProgradeToRetrogradeInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusProgradeToRetrogradeWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusProgradeToRetrogradeWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusProgradeToRetrogradeInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusProgradeToRetrogradeInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusProgradeToRetrogradeWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusProgradeToRetrogradeWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusRetrogradeToProgradeInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusRetrogradeToProgradeInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusRetrogradeToProgradeWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusRetrogradeToProgradeWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusRetrogradeToProgradeInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusRetrogradeToProgradeInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusRetrogradeToProgradeWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusRetrogradeToProgradeWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusGreatestElongationInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusGreatestElongationInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusGreatestElongationWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusGreatestElongationWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusGreatestElongationInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusGreatestElongationInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusGreatestElongationWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusGreatestElongationWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusGreatestElongationEastInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusGreatestElongationEastInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusGreatestElongationEastWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusGreatestElongationEastWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusGreatestElongationEastInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusGreatestElongationEastInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusGreatestElongationEastWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusGreatestElongationEastWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusGreatestElongationWestInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusGreatestElongationWestInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveLastSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusGreatestElongationWestWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusGreatestElongationWestWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusGreatestElongationWestInclusiveWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusGreatestElongationWestInclusiveWithInstance ( jde float64 , inst * Instance ) float64 {
return inclusiveNextSimpleEvent ( jde , func ( jde float64 ) float64 { return LastVenusGreatestElongationWestWithInstance ( jde , inst ) }, func ( jde float64 ) float64 { return NextVenusGreatestElongationWestWithInstance ( jde , inst ) })
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusGreatestElongationEastWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusGreatestElongationEastWithInstance ( jde float64 , inst * Instance ) float64 {
return nextVenusGreatestElongationTyped ( jde , true , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// NextVenusGreatestElongationWestWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func NextVenusGreatestElongationWestWithInstance ( jde float64 , inst * Instance ) float64 {
return nextVenusGreatestElongationTyped ( jde , false , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusGreatestElongationEastWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusGreatestElongationEastWithInstance ( jde float64 , inst * Instance ) float64 {
return lastVenusGreatestElongationTyped ( jde , true , inst )
2026-05-22 12:24:41 +08:00
}
2026-10-15 23:54:15 +08:00
// LastVenusGreatestElongationWestWithInstance 用指定星历实例求值;inst 为 nil 时用进程当前模型 / evaluation with an explicit instance; nil uses the process model.
func LastVenusGreatestElongationWestWithInstance ( jde float64 , inst * Instance ) float64 {
return lastVenusGreatestElongationTyped ( jde , false , inst )
2026-05-01 22:38:44 +08:00
}