Files
astro/basic/saturn_ring.go
T

140 lines
5.0 KiB
Go
Raw Normal View History

2026-05-01 22:38:44 +08:00
package basic
import (
"math"
"b612.me/astro/planet"
. "b612.me/astro/tools"
)
// SaturnRingParameters 土星环参数 / Saturn ring parameters.
func SaturnRingParameters(jde float64) (earthLatitude, sunLatitude, positionAngle, deltaU, majorAxis, minorAxis float64) {
return SaturnRingParametersN(jde, -1)
2026-05-01 22:38:44 +08:00
}
// SaturnRingParametersN 土星环参数(截断版) / truncated Saturn ring parameters.
func SaturnRingParametersN(jde float64, n int) (earthLatitude, sunLatitude, positionAngle, deltaU, majorAxis, minorAxis float64) {
inclination, node := saturnRingPlane(jde)
earthLon, earthLat := SaturnApparentLoBoN(jde, n)
sunLon, sunLat := saturnRingSunLoBo(jde, n, node)
2026-05-01 22:38:44 +08:00
earthLatitude = saturnRingLatitude(inclination, node, earthLon, earthLat)
sunLatitude = saturnRingLatitude(inclination, node, sunLon, sunLat)
positionAngle = saturnRingPositionAngle(jde, inclination, node, earthLon, earthLat)
2026-05-01 22:38:44 +08:00
earthU := saturnRingLongitude(inclination, node, earthLon, earthLat)
sunU := saturnRingLongitude(inclination, node, sunLon, sunLat)
deltaU = saturnRingLongitudeDelta(earthU, sunU)
earthDistance := EarthSaturnAwayN(jde, n)
2026-05-01 22:38:44 +08:00
majorAxis = 375.35 / earthDistance
minorAxis = majorAxis * math.Abs(Sin(earthLatitude))
return
}
// SaturnRingB 土星环张角 B / Saturn ring opening angle B.
func SaturnRingB(jde float64) float64 {
return SaturnRingBN(jde, -1)
2026-05-01 22:38:44 +08:00
}
// SaturnRingBN 土星环张角 B(截断版) / truncated Saturn ring opening angle B.
func SaturnRingBN(jde float64, n int) float64 {
earthLatitude, _, _, _, _, _ := SaturnRingParametersN(jde, n)
2026-05-01 22:38:44 +08:00
return earthLatitude
}
// SaturnRingSunB 土星环太阳侧张角 B' / Sun-side Saturn ring opening angle B'.
func SaturnRingSunB(jde float64) float64 {
return SaturnRingSunBN(jde, -1)
2026-05-01 22:38:44 +08:00
}
// SaturnRingSunBN 土星环太阳侧张角 B'(截断版) / truncated Sun-side Saturn ring opening angle B'.
func SaturnRingSunBN(jde float64, n int) float64 {
_, sunLatitude, _, _, _, _ := SaturnRingParametersN(jde, n)
2026-05-01 22:38:44 +08:00
return sunLatitude
}
// SaturnRingPositionAngle 土星环北半短轴位置角 / position angle of Saturn ring northern semiminor axis.
func SaturnRingPositionAngle(jde float64) float64 {
return SaturnRingPositionAngleN(jde, -1)
2026-05-01 22:38:44 +08:00
}
// SaturnRingPositionAngleN 土星环北半短轴位置角(截断版) / truncated position angle of Saturn ring northern semiminor axis.
func SaturnRingPositionAngleN(jde float64, n int) float64 {
_, _, positionAngle, _, _, _ := SaturnRingParametersN(jde, n)
2026-05-01 22:38:44 +08:00
return positionAngle
}
// SaturnRingDeltaU 太阳和地球在环面内的土星心黄经差 / difference of Saturnicentric ring longitudes.
func SaturnRingDeltaU(jde float64) float64 {
return SaturnRingDeltaUN(jde, -1)
2026-05-01 22:38:44 +08:00
}
// SaturnRingDeltaUN 太阳和地球在环面内的土星心黄经差(截断版) / truncated Saturnicentric ring longitude difference.
func SaturnRingDeltaUN(jde float64, n int) float64 {
_, _, _, deltaU, _, _ := SaturnRingParametersN(jde, n)
2026-05-01 22:38:44 +08:00
return deltaU
}
// SaturnRingAxis 土星环外缘长短轴,单位角秒 / outer ring axes in arcseconds.
func SaturnRingAxis(jde float64) (majorAxis, minorAxis float64) {
return SaturnRingAxisN(jde, -1)
2026-05-01 22:38:44 +08:00
}
// SaturnRingAxisN 土星环外缘长短轴(截断版),单位角秒 / truncated outer ring axes in arcseconds.
func SaturnRingAxisN(jde float64, n int) (majorAxis, minorAxis float64) {
_, _, _, _, majorAxis, minorAxis = SaturnRingParametersN(jde, n)
2026-05-01 22:38:44 +08:00
return
}
func saturnRingPlane(jd float64) (inclination, node float64) {
t := (jd - 2451545.0) / 36525.0
inclination = 28.075216 - 0.012998*t + 0.000004*t*t
node = 169.508470 + 1.394681*t + 0.000412*t*t
return
}
func saturnRingSunLoBo(jde float64, n int, node float64) (lon, lat float64) {
lon = planet.WherePlanetN(5, 0, jde, n)
lat = planet.WherePlanetN(5, 1, jde, n)
distance := planet.WherePlanetN(5, 2, jde, n)
2026-05-01 22:38:44 +08:00
lat -= 0.000764 * Cos(lon-node) / distance
lon -= 0.01759 / distance
return lon, lat
}
func saturnRingLatitude(inclination, node, lon, lat float64) float64 {
return ArcSin(Sin(inclination)*Cos(lat)*Sin(lon-node) - Cos(inclination)*Sin(lat))
}
func saturnRingLongitude(inclination, node, lon, lat float64) float64 {
y := Sin(inclination)*Sin(lat) + Cos(inclination)*Cos(lat)*Sin(lon-node)
x := Cos(lat) * Cos(lon-node)
return ArcTan2(y, x)
}
func saturnRingLongitudeDelta(a, b float64) float64 {
delta := math.Abs(Limit360(a - b))
if delta > 180 {
return 360 - delta
}
return delta
}
func saturnRingPositionAngle(jde, inclination, node, lon, lat float64) float64 {
poleLon := node - 90 + Nutation2000Bi(jde)
2026-05-01 22:38:44 +08:00
poleLat := 90 - inclination
eps := TrueObliquity(jde)
2026-05-01 22:38:44 +08:00
poleRa, poleDec := saturnRingEclipticToEquatorial(poleLon, poleLat, eps)
saturnRa, saturnDec := saturnRingEclipticToEquatorial(lon, lat, eps)
y := Cos(poleDec) * Sin(poleRa-saturnRa)
x := Sin(poleDec)*Cos(saturnDec) - Cos(poleDec)*Sin(saturnDec)*Cos(poleRa-saturnRa)
return ArcTan2(y, x)
}
func saturnRingEclipticToEquatorial(lon, lat, eps float64) (ra, dec float64) {
ra = ArcTan2(Sin(lon)*Cos(eps)-Tan(lat)*Sin(eps), Cos(lon))
dec = ArcSin(Sin(lat)*Cos(eps) + Cos(lat)*Sin(eps)*Sin(lon))
return
}