fix: 修正行星事件边界与留点计算
- 统一 UT 事件时刻与 TT 查询时刻的边界判断 - 将外行星留点搜索锚定到对应冲日周期 - 修正水星、金星合日、留、大距事件选择 - 统一七大行星视位置计算辅助逻辑 - 增加公开 Last/Next 边界和 JPL/NAOJ 基线回归测试
This commit is contained in:
+429
-158
@@ -3,6 +3,7 @@ package basic
|
||||
import (
|
||||
"math"
|
||||
|
||||
"b612.me/astro/planet"
|
||||
. "b612.me/astro/tools"
|
||||
)
|
||||
|
||||
@@ -33,6 +34,23 @@ func venusSunLongitudeDeltaN(jde float64, n int) float64 {
|
||||
return sub
|
||||
}
|
||||
|
||||
func venusConjunctionAngleDelta(diff float64) float64 {
|
||||
diff = Limit360(diff)
|
||||
if diff > 180 {
|
||||
diff -= 360
|
||||
}
|
||||
if diff < -180 {
|
||||
diff += 360
|
||||
}
|
||||
return diff
|
||||
}
|
||||
|
||||
func venusConjunctionHeliocentricDelta(jd, targetDeg float64, n int) float64 {
|
||||
planetLo := planet.WherePlanetN(2, 0, jd, n)
|
||||
earthLo := planet.WherePlanetN(-1, 0, jd, n)
|
||||
return venusConjunctionAngleDelta(planetLo - earthLo - targetDeg)
|
||||
}
|
||||
|
||||
func venusSunRADelta(jde float64) float64 {
|
||||
sub := Limit360(VenusApparentRa(jde) - SunApparentRa(jde))
|
||||
if sub > 180 {
|
||||
@@ -66,13 +84,94 @@ func venusRADerivativeN(jde, val float64, n int) float64 {
|
||||
return sub / (2 * val)
|
||||
}
|
||||
|
||||
func venusRAContinuousForMax(jde float64) float64 {
|
||||
ra := VenusApparentRa(jde)
|
||||
if ra < 180 {
|
||||
return ra + 360
|
||||
}
|
||||
return ra
|
||||
}
|
||||
|
||||
func venusRAContinuousForMaxN(jde float64, n int) float64 {
|
||||
ra := VenusApparentRaN(jde, n)
|
||||
if ra < 180 {
|
||||
return ra + 360
|
||||
}
|
||||
return ra
|
||||
}
|
||||
|
||||
func venusRAContinuousForMin(jde float64) float64 {
|
||||
ra := VenusApparentRa(jde)
|
||||
if ra > 180 {
|
||||
return ra - 360
|
||||
}
|
||||
return ra
|
||||
}
|
||||
|
||||
func venusRAContinuousForMinN(jde float64, n int) float64 {
|
||||
ra := VenusApparentRaN(jde, n)
|
||||
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
|
||||
}
|
||||
|
||||
func venusSunElongationN(jde float64, n int) float64 {
|
||||
lo1, bo1 := VenusApparentLoBoN(jde, n)
|
||||
lo2 := SunApparentLo(jde)
|
||||
lo2 := HSunApparentLoN(jde, n)
|
||||
bo2 := HSunTrueBoN(jde, n)
|
||||
return StarAngularSeparation(lo1, bo1, lo2, bo2)
|
||||
}
|
||||
|
||||
func venusTrueElongationN(jde float64, n int) float64 {
|
||||
earth := mercuryHelioN(-1, jde, n)
|
||||
planetPos := mercuryHelioN(2, jde, n)
|
||||
geo := mercuryGeocentric(planetPos, earth)
|
||||
return StarAngularSeparation(geo.lo, geo.bo, HSunTrueLoN(jde, n), HSunTrueBoN(jde, n))
|
||||
}
|
||||
|
||||
func venusElongationDerivative(jde, val float64) float64 {
|
||||
sub := VenusSunElongation(jde+val) - VenusSunElongation(jde-val)
|
||||
if sub > 180 {
|
||||
@@ -96,91 +195,98 @@ func venusElongationDerivativeN(jde, val float64, n int) float64 {
|
||||
}
|
||||
|
||||
func venusConjunction(jde float64, next uint8) float64 {
|
||||
//0=last 1=next
|
||||
nowSub := venusSunLongitudeDeltaN(jde, venusEventSearchN)
|
||||
pos := math.Abs(venusSunLongitudeDeltaN(jde+1/86400.0, venusEventSearchN)) - math.Abs(nowSub)
|
||||
if pos >= 0 && next == 1 && nowSub > 0 {
|
||||
jde += VENUS_S_PERIOD/8.0 + 2
|
||||
queryTT := jde
|
||||
direction := -1.0
|
||||
if next == 1 {
|
||||
direction = 1
|
||||
}
|
||||
if pos >= 0 && next == 1 && nowSub < 0 {
|
||||
jde += VENUS_S_PERIOD/6.0 + 2
|
||||
}
|
||||
if pos <= 0 && next == 0 && nowSub < 0 {
|
||||
jde -= VENUS_S_PERIOD/8.0 + 2
|
||||
}
|
||||
if pos <= 0 && next == 0 && nowSub > 0 {
|
||||
jde -= VENUS_S_PERIOD/6.0 + 2
|
||||
}
|
||||
for {
|
||||
nowSub := venusSunLongitudeDeltaN(jde, venusEventSearchN)
|
||||
pos := math.Abs(venusSunLongitudeDeltaN(jde+1/86400.0, venusEventSearchN)) - math.Abs(nowSub)
|
||||
if math.Abs(nowSub) > 24 || (pos > 0 && next == 1) || (pos < 0 && next == 0) {
|
||||
if next == 1 {
|
||||
jde += 8
|
||||
} else {
|
||||
jde -= 8
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
JD1 := jde
|
||||
for {
|
||||
JD0 := JD1
|
||||
stDegree := venusSunLongitudeDelta(JD0)
|
||||
stDegreep := (venusSunLongitudeDelta(JD0+0.000005) - venusSunLongitudeDelta(JD0-0.000005)) / 0.00001
|
||||
JD1 = JD0 - stDegree/stDegreep
|
||||
if math.Abs(JD1-JD0) <= 0.00001 {
|
||||
break
|
||||
left := queryTT
|
||||
leftVal := venusSunLongitudeDeltaN(left, venusEventSearchN)
|
||||
if math.Abs(leftVal) <= 30.0/86400.0 {
|
||||
exact := eventZeroRefine(left, 1.0, 0.000005, venusSunLongitudeDelta)
|
||||
if math.Abs(exact-queryTT) <= 1.0 {
|
||||
return TD2UT(exact, false)
|
||||
}
|
||||
}
|
||||
return TD2UT(JD1, false)
|
||||
const step = 8.0
|
||||
for i := 0; i < 80; i++ {
|
||||
right := queryTT + direction*step*float64(i+1)
|
||||
rightVal := venusSunLongitudeDeltaN(right, venusEventSearchN)
|
||||
if leftVal == 0 || rightVal == 0 || leftVal*rightVal <= 0 {
|
||||
center := (left + right) / 2.0
|
||||
halfWindow := math.Abs(right-left) / 2.0
|
||||
return TD2UT(eventZeroRefine(center, halfWindow, 0.000005, venusSunLongitudeDelta), false)
|
||||
}
|
||||
left = right
|
||||
leftVal = rightVal
|
||||
}
|
||||
return TD2UT(eventZeroRefine(queryTT, VENUS_S_PERIOD, 0.000005, venusSunLongitudeDelta), false)
|
||||
}
|
||||
|
||||
func venusConjunctionTypeAt(eventUT float64) bool {
|
||||
return EarthVenusAway(eventUT) <= EarthAway(eventUT)
|
||||
}
|
||||
|
||||
func nextVenusTypedConjunctionFromEvent(jde float64, inferior bool) float64 {
|
||||
date := NextVenusConjunctionStrict(jde)
|
||||
if venusConjunctionTypeAt(date) == inferior {
|
||||
return date
|
||||
}
|
||||
return NextVenusConjunctionStrict(eventUTNextQueryTT(date))
|
||||
}
|
||||
|
||||
func lastVenusTypedConjunctionFromEvent(jde float64, inferior bool) float64 {
|
||||
date := LastVenusConjunctionStrict(jde)
|
||||
if venusConjunctionTypeAt(date) == inferior {
|
||||
return date
|
||||
}
|
||||
return LastVenusConjunctionStrict(eventUTLastQueryTT(date))
|
||||
}
|
||||
|
||||
func LastVenusConjunction(jde float64) float64 {
|
||||
return venusConjunction(jde, 0)
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusConjunctionStrict, NextVenusConjunctionStrict)
|
||||
}
|
||||
|
||||
func NextVenusConjunction(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusConjunctionStrict, NextVenusConjunctionStrict)
|
||||
}
|
||||
|
||||
func LastVenusConjunctionStrict(jde float64) float64 {
|
||||
return venusConjunction(jde, 0)
|
||||
}
|
||||
|
||||
func NextVenusConjunctionStrict(jde float64) float64 {
|
||||
return venusConjunction(jde, 1)
|
||||
}
|
||||
|
||||
func nextVenusTypedConjunction(jde float64, inferior bool) float64 {
|
||||
return nextVenusTypedConjunctionFromEvent(jde, inferior)
|
||||
}
|
||||
|
||||
func lastVenusTypedConjunction(jde float64, inferior bool) float64 {
|
||||
return lastVenusTypedConjunctionFromEvent(jde, inferior)
|
||||
}
|
||||
|
||||
func NextVenusInferiorConjunction(jde float64) float64 {
|
||||
date := NextVenusConjunction(jde)
|
||||
if EarthVenusAway(date) > EarthAway(date) {
|
||||
return NextVenusConjunction(date + 2)
|
||||
}
|
||||
return date
|
||||
return nextVenusTypedConjunction(jde, true)
|
||||
}
|
||||
|
||||
func NextVenusSuperiorConjunction(jde float64) float64 {
|
||||
date := NextVenusConjunction(jde)
|
||||
if EarthVenusAway(date) < EarthAway(date) {
|
||||
return NextVenusConjunction(date + 2)
|
||||
}
|
||||
return date
|
||||
return nextVenusTypedConjunction(jde, false)
|
||||
}
|
||||
|
||||
func LastVenusInferiorConjunction(jde float64) float64 {
|
||||
date := LastVenusConjunction(jde)
|
||||
if EarthVenusAway(date) > EarthAway(date) {
|
||||
return LastVenusConjunction(date - 2)
|
||||
}
|
||||
return date
|
||||
return lastVenusTypedConjunction(jde, true)
|
||||
}
|
||||
|
||||
func LastVenusSuperiorConjunction(jde float64) float64 {
|
||||
date := LastVenusConjunction(jde)
|
||||
if EarthVenusAway(date) < EarthAway(date) {
|
||||
return LastVenusConjunction(date - 2)
|
||||
}
|
||||
return date
|
||||
return lastVenusTypedConjunction(jde, false)
|
||||
}
|
||||
|
||||
func venusRetrograde(jde float64) float64 {
|
||||
//0=last 1=next
|
||||
lastHe := LastVenusConjunction(jde)
|
||||
nextHe := NextVenusConjunction(jde)
|
||||
lastHe := LastVenusConjunctionStrict(jde)
|
||||
nextHe := NextVenusConjunctionStrict(jde)
|
||||
nowSub := venusSunRADelta(jde)
|
||||
if nowSub > 0 {
|
||||
jde = lastHe + ((nextHe - lastHe) / 5.0 * 3.5)
|
||||
@@ -213,152 +319,317 @@ func venusRetrograde(jde float64) float64 {
|
||||
}
|
||||
|
||||
func NextVenusRetrograde(jde float64) float64 {
|
||||
date := venusRetrograde(jde)
|
||||
if date < jde {
|
||||
nextHe := NextVenusConjunction(jde)
|
||||
return venusRetrograde(nextHe + 2)
|
||||
p2r := NextVenusProgradeToRetrograde(jde)
|
||||
r2p := NextVenusRetrogradeToPrograde(jde)
|
||||
if sameEventJD(p2r, r2p) {
|
||||
return p2r
|
||||
}
|
||||
return date
|
||||
if p2r < r2p {
|
||||
return p2r
|
||||
}
|
||||
return r2p
|
||||
}
|
||||
|
||||
func LastVenusRetrograde(jde float64) float64 {
|
||||
lastHe := LastVenusConjunction(jde)
|
||||
date := venusRetrograde(lastHe + 2)
|
||||
if date > jde {
|
||||
lastLastHe := LastVenusConjunction(lastHe - 2)
|
||||
return venusRetrograde(lastLastHe + 2)
|
||||
p2r := LastVenusProgradeToRetrograde(jde)
|
||||
r2p := LastVenusRetrogradeToPrograde(jde)
|
||||
if sameEventJD(p2r, r2p) {
|
||||
return p2r
|
||||
}
|
||||
return date
|
||||
if p2r > r2p {
|
||||
return p2r
|
||||
}
|
||||
return r2p
|
||||
}
|
||||
|
||||
func venusStationInWindow(start, end float64, progradeToRetrograde bool) float64 {
|
||||
var best float64
|
||||
if progradeToRetrograde {
|
||||
guess := scanWindowForMax(start, end, 2.0, func(jd float64) float64 {
|
||||
return venusRAContinuousForMaxN(jd, venusEventSearchN)
|
||||
})
|
||||
best = venusRAExtremumRefine(guess, start, end, 1.0, func(jd float64) float64 {
|
||||
return venusRAContinuousForMax(jd)
|
||||
})
|
||||
} else {
|
||||
guess := scanWindowForMax(start, end, 2.0, func(jd float64) float64 {
|
||||
return -venusRAContinuousForMinN(jd, venusEventSearchN)
|
||||
})
|
||||
best = venusRAExtremumRefine(guess, start, end, 1.0, func(jd float64) float64 {
|
||||
return -venusRAContinuousForMin(jd)
|
||||
})
|
||||
}
|
||||
return TD2UT(best, false)
|
||||
}
|
||||
|
||||
func venusProgradeToRetrogradeAroundInferior(inferior float64) float64 {
|
||||
return venusStationInWindow(inferior-30.0, inferior-14.0, true)
|
||||
}
|
||||
|
||||
func venusRetrogradeToProgradeAroundInferior(inferior float64) float64 {
|
||||
return venusStationInWindow(inferior+14.0, inferior+24.0, false)
|
||||
}
|
||||
|
||||
func NextVenusProgradeToRetrograde(jde float64) float64 {
|
||||
date := NextVenusRetrograde(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub > 180 {
|
||||
return NextVenusRetrograde(date + VENUS_S_PERIOD/2)
|
||||
inferior := NextVenusInferiorConjunction(jde)
|
||||
for {
|
||||
date := venusProgradeToRetrogradeAroundInferior(inferior)
|
||||
if eventUTQueryAfterOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
inferior = NextVenusInferiorConjunction(eventUTNextQueryTT(inferior))
|
||||
}
|
||||
return date
|
||||
}
|
||||
|
||||
func NextVenusRetrogradeToPrograde(jde float64) float64 {
|
||||
date := NextVenusRetrograde(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub < 180 {
|
||||
return NextVenusRetrograde(date + 12)
|
||||
inferior := LastVenusInferiorConjunction(jde)
|
||||
for {
|
||||
date := venusRetrogradeToProgradeAroundInferior(inferior)
|
||||
if eventUTQueryAfterOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
inferior = NextVenusInferiorConjunction(eventUTNextQueryTT(inferior))
|
||||
}
|
||||
return date
|
||||
}
|
||||
|
||||
func LastVenusProgradeToRetrograde(jde float64) float64 {
|
||||
date := LastVenusRetrograde(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub > 180 {
|
||||
return LastVenusRetrograde(date - 12)
|
||||
inferior := NextVenusInferiorConjunction(jde)
|
||||
for {
|
||||
date := venusProgradeToRetrogradeAroundInferior(inferior)
|
||||
if eventUTQueryBeforeOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
inferior = LastVenusInferiorConjunction(eventUTLastQueryTT(inferior))
|
||||
}
|
||||
return date
|
||||
}
|
||||
|
||||
func LastVenusRetrogradeToPrograde(jde float64) float64 {
|
||||
date := LastVenusRetrograde(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub < 180 {
|
||||
return LastVenusRetrograde(date - VENUS_S_PERIOD/2)
|
||||
inferior := LastVenusInferiorConjunction(jde)
|
||||
for {
|
||||
date := venusRetrogradeToProgradeAroundInferior(inferior)
|
||||
if eventUTQueryBeforeOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
inferior = LastVenusInferiorConjunction(eventUTLastQueryTT(inferior))
|
||||
}
|
||||
return date
|
||||
}
|
||||
|
||||
func VenusSunElongation(jde float64) float64 {
|
||||
lo1, bo1 := VenusApparentLoBo(jde)
|
||||
lo2 := SunApparentLo(jde)
|
||||
lo2 := HSunApparentLo(jde)
|
||||
bo2 := HSunTrueBo(jde)
|
||||
return StarAngularSeparation(lo1, bo1, lo2, bo2)
|
||||
}
|
||||
|
||||
func venusGreatestElongation(jde float64) float64 {
|
||||
lastHe := LastVenusConjunction(jde)
|
||||
nextHe := NextVenusConjunction(jde)
|
||||
nowSub := venusSunRADelta(jde)
|
||||
if nowSub > 0 {
|
||||
jde = lastHe + ((nextHe - lastHe) / 5.0 * 2.5)
|
||||
} else {
|
||||
jde = lastHe + ((nextHe - lastHe) / 5.0)
|
||||
}
|
||||
for {
|
||||
nowSub := venusElongationDerivativeN(jde, 1.0/86400.0, venusEventSearchN)
|
||||
if math.Abs(nowSub) > 0.15 {
|
||||
jde += 5
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
JD1 := jde
|
||||
for {
|
||||
JD0 := JD1
|
||||
stDegree := venusElongationDerivative(JD0, 2.0/86400.0)
|
||||
stDegreep := (venusElongationDerivative(JD0+15.0/86400.0, 2.0/86400.0) - venusElongationDerivative(JD0-15.0/86400.0, 2.0/86400.0)) / (30.0 / 86400.0)
|
||||
JD1 = JD0 - stDegree/stDegreep
|
||||
if math.Abs(JD1-JD0) <= 30.0/86400.0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
min := eventZeroRefine(JD1, 15.0/86400.0, 0.5/86400.0, func(jd float64) float64 {
|
||||
return venusElongationDerivative(jd, 0.5/86400.0)
|
||||
func venusGreatestElongationInWindow(start, end float64) float64 {
|
||||
best := maximizeInWindow(start, end, 5.0, func(jd float64) float64 {
|
||||
return venusTrueElongationN(jd, venusEventSearchN)
|
||||
}, func(jd float64) float64 {
|
||||
return venusTrueElongationN(jd, -1)
|
||||
})
|
||||
//fmt.Println((min - lastHe) / (nextHe - lastHe))
|
||||
return TD2UT(min, false)
|
||||
return TD2UT(best, false)
|
||||
}
|
||||
|
||||
func venusEastElongationWindowEndingAt(inferior float64) (float64, float64) {
|
||||
lastSuperior := LastVenusSuperiorConjunction(eventUTLastQueryTT(inferior))
|
||||
return lastSuperior + innerEventEpsilon, inferior - innerEventEpsilon
|
||||
}
|
||||
|
||||
func venusWestElongationWindowEndingAt(superior float64) (float64, float64) {
|
||||
lastInferior := LastVenusInferiorConjunction(eventUTLastQueryTT(superior))
|
||||
return lastInferior + innerEventEpsilon, superior - innerEventEpsilon
|
||||
}
|
||||
|
||||
func venusEastElongationWindowContaining(jde float64) (float64, float64) {
|
||||
nextInferior := NextVenusInferiorConjunction(jde)
|
||||
start, end := venusEastElongationWindowEndingAt(nextInferior)
|
||||
if eventUTQueryBeforeOrEqual(start, jde) && eventUTQueryAfterOrEqual(end, jde) {
|
||||
return start, end
|
||||
}
|
||||
currentInferior := LastVenusInferiorConjunction(jde)
|
||||
return venusEastElongationWindowEndingAt(currentInferior)
|
||||
}
|
||||
|
||||
func venusWestElongationWindowContaining(jde float64) (float64, float64) {
|
||||
nextSuperior := NextVenusSuperiorConjunction(jde)
|
||||
start, end := venusWestElongationWindowEndingAt(nextSuperior)
|
||||
if eventUTQueryBeforeOrEqual(start, jde) && eventUTQueryAfterOrEqual(end, jde) {
|
||||
return start, end
|
||||
}
|
||||
currentSuperior := LastVenusSuperiorConjunction(jde)
|
||||
return venusWestElongationWindowEndingAt(currentSuperior)
|
||||
}
|
||||
|
||||
func nextVenusGreatestElongationTyped(jde float64, east bool) float64 {
|
||||
if east {
|
||||
start, windowEnd := venusEastElongationWindowContaining(jde)
|
||||
for {
|
||||
date := venusGreatestElongationInWindow(start, windowEnd)
|
||||
if eventUTQueryAfterOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
nextInferior := NextVenusInferiorConjunction(eventUTNextQueryTT(windowEnd))
|
||||
start, windowEnd = venusEastElongationWindowEndingAt(nextInferior)
|
||||
}
|
||||
}
|
||||
start, windowEnd := venusWestElongationWindowContaining(jde)
|
||||
for {
|
||||
date := venusGreatestElongationInWindow(start, windowEnd)
|
||||
if eventUTQueryAfterOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
nextSuperior := NextVenusSuperiorConjunction(eventUTNextQueryTT(windowEnd))
|
||||
start, windowEnd = venusWestElongationWindowEndingAt(nextSuperior)
|
||||
}
|
||||
}
|
||||
|
||||
func lastVenusGreatestElongationTyped(jde float64, east bool) float64 {
|
||||
if east {
|
||||
start, windowEnd := venusEastElongationWindowContaining(jde)
|
||||
for {
|
||||
date := venusGreatestElongationInWindow(start, windowEnd)
|
||||
if eventUTQueryBeforeOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
prevInferior := LastVenusInferiorConjunction(eventUTLastQueryTT(start))
|
||||
start, windowEnd = venusEastElongationWindowEndingAt(prevInferior)
|
||||
}
|
||||
}
|
||||
start, windowEnd := venusWestElongationWindowContaining(jde)
|
||||
for {
|
||||
date := venusGreatestElongationInWindow(start, windowEnd)
|
||||
if eventUTQueryBeforeOrEqual(date, jde) {
|
||||
return date
|
||||
}
|
||||
prevSuperior := LastVenusSuperiorConjunction(eventUTLastQueryTT(start))
|
||||
start, windowEnd = venusWestElongationWindowEndingAt(prevSuperior)
|
||||
}
|
||||
}
|
||||
|
||||
func venusGreatestElongation(jde float64) float64 {
|
||||
east := venusSunRADelta(jde) > 0
|
||||
if east {
|
||||
return nextVenusGreatestElongationTyped(jde, true)
|
||||
}
|
||||
return nextVenusGreatestElongationTyped(jde, false)
|
||||
}
|
||||
|
||||
func NextVenusGreatestElongation(jde float64) float64 {
|
||||
date := venusGreatestElongation(jde)
|
||||
if date < jde {
|
||||
nextHe := NextVenusConjunction(jde)
|
||||
return venusGreatestElongation(nextHe + 2)
|
||||
east := NextVenusGreatestElongationEast(jde)
|
||||
west := NextVenusGreatestElongationWest(jde)
|
||||
if sameEventJD(east, west) {
|
||||
return east
|
||||
}
|
||||
return date
|
||||
if east < west {
|
||||
return east
|
||||
}
|
||||
return west
|
||||
}
|
||||
|
||||
func LastVenusGreatestElongation(jde float64) float64 {
|
||||
lastHe := LastVenusConjunction(jde)
|
||||
date := venusGreatestElongation(lastHe + 2)
|
||||
if date > jde {
|
||||
lastLastHe := LastVenusConjunction(lastHe - 2)
|
||||
return venusGreatestElongation(lastLastHe + 2)
|
||||
east := LastVenusGreatestElongationEast(jde)
|
||||
west := LastVenusGreatestElongationWest(jde)
|
||||
if sameEventJD(east, west) {
|
||||
return east
|
||||
}
|
||||
return date
|
||||
if east > west {
|
||||
return east
|
||||
}
|
||||
return west
|
||||
}
|
||||
|
||||
func LastVenusInferiorConjunctionInclusive(jde float64) float64 {
|
||||
date := LastVenusConjunction(jde)
|
||||
if venusConjunctionTypeAt(date) {
|
||||
return date
|
||||
}
|
||||
return LastVenusConjunction(eventUTLastQueryTT(date))
|
||||
}
|
||||
|
||||
func NextVenusInferiorConjunctionInclusive(jde float64) float64 {
|
||||
date := NextVenusConjunction(jde)
|
||||
if venusConjunctionTypeAt(date) {
|
||||
return date
|
||||
}
|
||||
return NextVenusConjunction(eventUTNextQueryTT(date))
|
||||
}
|
||||
|
||||
func LastVenusSuperiorConjunctionInclusive(jde float64) float64 {
|
||||
date := LastVenusConjunction(jde)
|
||||
if !venusConjunctionTypeAt(date) {
|
||||
return date
|
||||
}
|
||||
return LastVenusConjunction(eventUTLastQueryTT(date))
|
||||
}
|
||||
|
||||
func NextVenusSuperiorConjunctionInclusive(jde float64) float64 {
|
||||
date := NextVenusConjunction(jde)
|
||||
if !venusConjunctionTypeAt(date) {
|
||||
return date
|
||||
}
|
||||
return NextVenusConjunction(eventUTNextQueryTT(date))
|
||||
}
|
||||
|
||||
func LastVenusRetrogradeInclusive(jde float64) float64 {
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusRetrograde, NextVenusRetrograde)
|
||||
}
|
||||
|
||||
func NextVenusRetrogradeInclusive(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusRetrograde, NextVenusRetrograde)
|
||||
}
|
||||
|
||||
func LastVenusProgradeToRetrogradeInclusive(jde float64) float64 {
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusProgradeToRetrograde, NextVenusProgradeToRetrograde)
|
||||
}
|
||||
|
||||
func NextVenusProgradeToRetrogradeInclusive(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusProgradeToRetrograde, NextVenusProgradeToRetrograde)
|
||||
}
|
||||
|
||||
func LastVenusRetrogradeToProgradeInclusive(jde float64) float64 {
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusRetrogradeToPrograde, NextVenusRetrogradeToPrograde)
|
||||
}
|
||||
|
||||
func NextVenusRetrogradeToProgradeInclusive(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusRetrogradeToPrograde, NextVenusRetrogradeToPrograde)
|
||||
}
|
||||
|
||||
func LastVenusGreatestElongationInclusive(jde float64) float64 {
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusGreatestElongation, NextVenusGreatestElongation)
|
||||
}
|
||||
|
||||
func NextVenusGreatestElongationInclusive(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusGreatestElongation, NextVenusGreatestElongation)
|
||||
}
|
||||
|
||||
func LastVenusGreatestElongationEastInclusive(jde float64) float64 {
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusGreatestElongationEast, NextVenusGreatestElongationEast)
|
||||
}
|
||||
|
||||
func NextVenusGreatestElongationEastInclusive(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusGreatestElongationEast, NextVenusGreatestElongationEast)
|
||||
}
|
||||
|
||||
func LastVenusGreatestElongationWestInclusive(jde float64) float64 {
|
||||
return inclusiveLastSimpleEvent(jde, LastVenusGreatestElongationWest, NextVenusGreatestElongationWest)
|
||||
}
|
||||
|
||||
func NextVenusGreatestElongationWestInclusive(jde float64) float64 {
|
||||
return inclusiveNextSimpleEvent(jde, LastVenusGreatestElongationWest, NextVenusGreatestElongationWest)
|
||||
}
|
||||
|
||||
func NextVenusGreatestElongationEast(jde float64) float64 {
|
||||
date := NextVenusGreatestElongation(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub > 180 {
|
||||
return NextVenusGreatestElongation(date + 1)
|
||||
}
|
||||
return date
|
||||
return nextVenusGreatestElongationTyped(jde, true)
|
||||
}
|
||||
|
||||
func NextVenusGreatestElongationWest(jde float64) float64 {
|
||||
date := NextVenusGreatestElongation(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub < 180 {
|
||||
return NextVenusGreatestElongation(date + 1)
|
||||
}
|
||||
return date
|
||||
return nextVenusGreatestElongationTyped(jde, false)
|
||||
}
|
||||
|
||||
func LastVenusGreatestElongationEast(jde float64) float64 {
|
||||
date := LastVenusGreatestElongation(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub > 180 {
|
||||
return LastVenusGreatestElongation(date - 1)
|
||||
}
|
||||
return date
|
||||
return lastVenusGreatestElongationTyped(jde, true)
|
||||
}
|
||||
|
||||
func LastVenusGreatestElongationWest(jde float64) float64 {
|
||||
date := LastVenusGreatestElongation(jde)
|
||||
sub := Limit360(VenusApparentRa(date) - SunApparentRa(date))
|
||||
if sub < 180 {
|
||||
return LastVenusGreatestElongation(date - 1)
|
||||
}
|
||||
return date
|
||||
return lastVenusGreatestElongationTyped(jde, false)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user