astro/basic/mars.go
starainrt 34ff6a36ae
fix: 修正行星事件边界与留点计算
- 统一 UT 事件时刻与 TT 查询时刻的边界判断
- 将外行星留点搜索锚定到对应冲日周期
- 修正水星、金星合日、留、大距事件选择
- 统一七大行星视位置计算辅助逻辑
- 增加公开 Last/Next 边界和 JPL/NAOJ 基线回归测试
2026-05-22 12:24:41 +08:00

209 lines
5.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package basic
import (
"math"
"b612.me/astro/planet"
. "b612.me/astro/tools"
)
func MarsL(jd float64) float64 {
return planet.WherePlanet(3, 0, jd)
}
func MarsB(jd float64) float64 {
return planet.WherePlanet(3, 1, jd)
}
func MarsR(jd float64) float64 {
return planet.WherePlanet(3, 2, jd)
}
func AMarsX(jd float64) float64 {
l := MarsL(jd)
b := MarsB(jd)
r := MarsR(jd)
el := planet.WherePlanet(-1, 0, jd)
eb := planet.WherePlanet(-1, 1, jd)
er := planet.WherePlanet(-1, 2, jd)
x := r*Cos(b)*Cos(l) - er*Cos(eb)*Cos(el)
return x
}
func AMarsY(jd float64) float64 {
l := MarsL(jd)
b := MarsB(jd)
r := MarsR(jd)
el := planet.WherePlanet(-1, 0, jd)
eb := planet.WherePlanet(-1, 1, jd)
er := planet.WherePlanet(-1, 2, jd)
y := r*Cos(b)*Sin(l) - er*Cos(eb)*Sin(el)
return y
}
func AMarsZ(jd float64) float64 {
//l := MarsL(jd)
b := MarsB(jd)
r := MarsR(jd)
// el := planet.WherePlanet(-1, 0, jd)
eb := planet.WherePlanet(-1, 1, jd)
er := planet.WherePlanet(-1, 2, jd)
z := r*Sin(b) - er*Sin(eb)
return z
}
func AMarsXYZ(jd float64) (float64, float64, float64) {
l := MarsL(jd)
b := MarsB(jd)
r := MarsR(jd)
el := planet.WherePlanet(-1, 0, jd)
eb := planet.WherePlanet(-1, 1, jd)
er := planet.WherePlanet(-1, 2, jd)
x := r*Cos(b)*Cos(l) - er*Cos(eb)*Cos(el)
y := r*Cos(b)*Sin(l) - er*Cos(eb)*Sin(el)
z := r*Sin(b) - er*Sin(eb)
return x, y, z
}
func MarsApparentRa(jd float64) float64 {
lo, bo := MarsApparentLoBo(jd)
eps := TrueObliquity(jd)
ra := math.Atan2((Sin(lo)*Cos(eps) - Tan(bo)*Sin(eps)), Cos(lo))
ra = ra * 180 / math.Pi
return Limit360(ra)
}
func MarsApparentDec(jd float64) float64 {
lo, bo := MarsApparentLoBo(jd)
eps := TrueObliquity(jd)
dec := ArcSin(Sin(bo)*Cos(eps) + Cos(bo)*Sin(eps)*Sin(lo))
return dec
}
func MarsApparentRaDec(jd float64) (float64, float64) {
lo, bo := MarsApparentLoBo(jd)
eps := TrueObliquity(jd)
ra := math.Atan2((Sin(lo)*Cos(eps) - Tan(bo)*Sin(eps)), Cos(lo))
ra = ra * 180 / math.Pi
dec := ArcSin(Sin(bo)*Cos(eps) + Cos(bo)*Sin(eps)*Sin(lo))
return Limit360(ra), dec
}
func EarthMarsAway(jd float64) float64 {
return planetEarthAwayExplicitN(3, jd, -1)
}
func MarsApparentLo(jd float64) float64 {
geo, _ := planetApparentGeocentricPositionN(3, jd, -1)
return geo.lo
}
func MarsApparentBo(jd float64) float64 {
geo, _ := planetApparentGeocentricPositionN(3, jd, -1)
return geo.bo
}
func MarsApparentLoBo(jd float64) (float64, float64) {
geo, _ := planetApparentGeocentricPositionN(3, jd, -1)
return geo.lo, geo.bo
}
func MarsTrueLoBo(jd float64) (float64, float64) {
geo, _ := planetTrueGeocentricPositionN(3, jd, -1)
return geo.lo, geo.bo
}
func MarsTrueLo(jd float64) float64 {
geo, _ := planetTrueGeocentricPositionN(3, jd, -1)
return geo.lo
}
func MarsMag(jd float64) float64 {
sunDistance := MarsR(jd)
earthDistance := EarthMarsAway(jd)
earthSunDistance := planet.WherePlanet(-1, 2, jd)
i := (sunDistance*sunDistance + earthDistance*earthDistance - earthSunDistance*earthSunDistance) / (2 * sunDistance * earthDistance)
i = ArcCos(i)
mag := -1.52 + 5*math.Log10(sunDistance*earthDistance) + 0.016*i
return FloatRound(mag, 2)
}
func MarsHeight(jde, lon, lat, timezone float64) float64 {
// 转换为世界时
utcJde := jde - timezone/24.0
// 计算视恒星时
ra, dec := MarsApparentRaDec(TD2UT(utcJde, true))
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
// 计算时角
hourAngle := Limit360(st - ra)
// 高度角、时角与天球座标三角转换公式
// sin(h)=sin(lat)*sin(dec)+cos(dec)*cos(lat)*cos(hourAngle)
sinHeight := Sin(lat)*Sin(dec) + Cos(dec)*Cos(lat)*Cos(hourAngle)
return ArcSin(sinHeight)
}
func MarsAzimuth(jde, lon, lat, timezone float64) float64 {
// 转换为世界时
utcJde := jde - timezone/24.0
// 计算视恒星时
ra, dec := MarsApparentRaDec(TD2UT(utcJde, true))
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
// 计算时角
hourAngle := Limit360(st - ra)
// 三角转换公式
tanAzimuth := Sin(hourAngle) / (Cos(hourAngle)*Sin(lat) - Tan(dec)*Cos(lat))
azimuth := ArcTan(tanAzimuth)
if azimuth < 0 {
if hourAngle/15 < 12 {
return azimuth + 360
}
return azimuth + 180
}
if hourAngle/15 < 12 {
return azimuth + 180
}
return azimuth
}
func MarsHourAngle(jd, lon, timezone float64) float64 {
siderealLongitude := Limit360(ApparentSiderealTime(jd-timezone/24)*15 + lon)
hourAngle := siderealLongitude - MarsApparentRa(TD2UT(jd-timezone/24.0, true))
if hourAngle < 0 {
hourAngle += 360
}
return hourAngle
}
func MarsCulminationTime(jde, lon, timezone float64) float64 {
//jde 世界时,非力学时,当地时区 0时无需转换力学时
//ra,dec 瞬时天球座标非J2000等时间天球坐标
jde = math.Floor(jde) + 0.5
estimateJD := jde + Limit360(360-MarsHourAngle(jde, lon, timezone))/15.0/24.0*0.99726851851851851851
normalizedHourAngle := func(jde, lon, timezone float64) float64 {
currentHourAngle := MarsHourAngle(jde, lon, timezone)
if currentHourAngle < 180 {
currentHourAngle += 360
}
return currentHourAngle
}
for {
prevJD := estimateJD
hourAngleDelta := normalizedHourAngle(prevJD, lon, timezone) - 360
hourAngleSlope := (normalizedHourAngle(prevJD+0.000005, lon, timezone) - normalizedHourAngle(prevJD-0.000005, lon, timezone)) / 0.00001
estimateJD = prevJD - hourAngleDelta/hourAngleSlope
if math.Abs(estimateJD-prevJD) <= 0.00001 {
break
}
}
return estimateJD
}
func MarsRiseTime(jd, lon, lat, timezone, aeroCorrection, observerHeight float64) (float64, error) {
return marsRiseDown(jd, lon, lat, timezone, aeroCorrection, observerHeight, true)
}
func MarsSetTime(jd, lon, lat, timezone, aeroCorrection, observerHeight float64) (float64, error) {
return marsRiseDown(jd, lon, lat, timezone, aeroCorrection, observerHeight, false)
}
func marsRiseDown(jd, lon, lat, timezone, aeroCorrection, observerHeight float64, isRise bool) (float64, error) {
return planetRiseDown(jd, lon, lat, timezone, aeroCorrection, observerHeight, isRise, MarsCulminationTime, MarsHeight, MarsApparentDec)
}