astro/planet/planet.go

112 lines
2.6 KiB
Go
Raw Normal View History

2019-10-24 10:44:21 +08:00
package planet
import (
. "b612.me/astro/tools"
"math"
2019-10-24 10:44:21 +08:00
)
// WherePlanet returns the full VSOP result for the selected body and coordinate.
func WherePlanet(xt, zn int, jd float64) float64 {
return WherePlanetN(xt, zn, jd, -1)
}
// WherePlanetN returns the VSOP result for the selected body and coordinate.
// When n < 0, all terms are used. Otherwise n follows the original eph0.js
// truncation semantics: keep roughly n principal terms from the 0th order
// series and scale higher-order series proportionally.
func WherePlanetN(xt, zn int, jd float64, n int) float64 {
sata := 0
if xt == -1 {
xt = 0
sata = 1
}
2019-10-24 10:44:21 +08:00
rad := 180.0000 * 3600.0000 / math.Pi
t := (jd - 2451545) / 36525.0000
t /= 10 // 转为儒略千年数
body := planetViews[xt]
coord := body.coords[zn]
baseOrderTerms := len(coord.orders[0])
2019-10-24 10:44:21 +08:00
tn := float64(1)
var v float64
for i, series := range coord.orders {
seriesLength := len(series)
if seriesLength == 0 {
continue
}
termLimit := seriesLength
if n >= 0 {
termLimit = int(math.Floor(3*float64(n)*float64(seriesLength)/float64(baseOrderTerms) + 0.5))
if i != 0 {
termLimit += 3
}
if termLimit > seriesLength {
termLimit = seriesLength
}
2019-10-24 10:44:21 +08:00
}
var c float64
for j := 0; j < termLimit; j += 3 {
c += series[j] * math.Cos(series[j+1]+t*series[j+2])
2019-10-24 10:44:21 +08:00
}
v += c * tn
tn *= t
2019-10-24 10:44:21 +08:00
}
v /= body.scale
if xt == 0 { // 地球
t2 := t * t
t3 := t2 * t // 千年数的各次方
if zn == 0 {
v += (-0.0728 - 2.7702*t - 1.1019*t2 - 0.0996*t3) / rad
} else if zn == 1 {
v += (+0.0000 + 0.0004*t + 0.0004*t2 - 0.0026*t3) / rad
} else if zn == 2 {
v += (-0.0020 + 0.0044*t + 0.0213*t2 - 0.0250*t3) / 1000000
2019-10-24 10:44:21 +08:00
}
} else { // 其它行星
planetCorrections := []float64{
// 经(角秒), 纬(角秒), 距(10-6AU)
-0.08631, +0.00039, -0.00008, // 水星
-0.07447, +0.00006, +0.00017, // 金星
-0.07135, -0.00026, -0.00176, // 火星
-0.20239, +0.00273, -0.00347, // 木星
-0.25486, +0.00276, +0.42926, // 土星
+0.24588, +0.00345, -14.46266, // 天王星
-0.95116, +0.02481, +58.30651, // 海王星
2019-10-24 10:44:21 +08:00
}
dv := planetCorrections[(xt-1)*3+zn]
if zn == 0 {
v += -3 * t / rad
2019-10-24 10:44:21 +08:00
}
if zn == 2 {
v += dv / 1000000
} else {
v += dv / rad
}
}
if zn == 0 && xt == 0 {
if sata != 0 {
return Limit360(v * 180 / math.Pi)
}
return Limit360(v*180/math.Pi + 180)
}
if zn == 1 && xt == 0 {
if sata != 0 {
return v * 180 / math.Pi
}
return -(v * 180 / math.Pi)
}
if xt > 0 && zn == 1 {
return v * 180 / math.Pi
}
if xt > 0 && zn == 0 {
return Limit360(v * 180 / math.Pi)
}
return v
}