044f2f4381
- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
200 lines
7.5 KiB
Go
200 lines
7.5 KiB
Go
package basic
|
||
|
||
import "math"
|
||
|
||
// Uranus 北极 J2000 赤经、赤纬与扁率。
|
||
const (
|
||
uranusPoleRA = 257.311
|
||
uranusPoleDec = -15.175
|
||
uranusFlattening = 0.02293
|
||
j2000ObliquityDeg = 23.4392911
|
||
)
|
||
|
||
// planetMagnitude2018 用 Mallama & Hilton 2018 模型求视星等;index 为 1..7(水星..海王星)。
|
||
// 超出模型相位角范围返回 NaN。
|
||
func planetMagnitude2018(index int, jde float64, inst *Instance) float64 {
|
||
r := planetRWithInstance(index, jde, inst)
|
||
delta := planetEarthAwayWithInstance(index, jde, inst)
|
||
earthR := planetRWithInstance(-1, jde, inst)
|
||
if !(r > 0) || !(delta > 0) || !(earthR > 0) {
|
||
return math.NaN()
|
||
}
|
||
cosPhase := (r*r + delta*delta - earthR*earthR) / (2 * r * delta)
|
||
a := math.Acos(math.Max(-1, math.Min(1, cosPhase))) * 180 / math.Pi
|
||
distance := 5 * math.Log10(r*delta)
|
||
switch index {
|
||
case 1:
|
||
return -0.613 + a*(6.3280e-2+a*(-1.6336e-3+a*(3.3644e-5+a*(-3.4265e-7+a*(1.6893e-9-3.0334e-12*a))))) + distance
|
||
case 2:
|
||
if a <= 163.7 {
|
||
return -4.384 + a*(-1.044e-3+a*(3.687e-4+a*(-2.814e-6+8.938e-9*a))) + distance
|
||
}
|
||
return 236.05828 + a*(-2.81914+8.39034e-3*a) + distance
|
||
case 3:
|
||
phys := MarsPhysicalNWithInstance(jde, -1, inst)
|
||
lon := PlanetCoordinateNWithInstance(3, 0, jde, -1, inst)
|
||
return marsMagnitude2018(r, delta, a, phys.SubEarthLongitude, phys.SubSolarLongitude, lon)
|
||
case 4:
|
||
if a <= 12 {
|
||
return -9.395 + a*(-3.7e-4+6.16e-4*a) + distance
|
||
}
|
||
x := a / 180
|
||
albedo := 1 + x*(-1.507+x*(-0.363+x*(-0.062+x*(2.809-1.876*x))))
|
||
if !(albedo > 0) {
|
||
return math.NaN()
|
||
}
|
||
return -9.428 - 2.5*math.Log10(albedo) + distance
|
||
case 5:
|
||
if a > 6.5 {
|
||
return math.NaN()
|
||
}
|
||
earthLat, sunLat, _, _, _, _ := saturnRingParametersWithInstance(jde, inst)
|
||
be, bs := earthLat*rad, sunLat*rad
|
||
tilt := 0.0
|
||
if be*bs > 0 {
|
||
tilt = math.Abs(math.Sin(math.Sqrt(be * bs)))
|
||
}
|
||
return -8.914 - 1.825*tilt + 0.026*a - 0.378*tilt*math.Exp(-2.25*a) + distance
|
||
case 6:
|
||
phase := 0.0
|
||
if a > 3.1 {
|
||
phase = a * (6.587e-3 + 1.045e-4*a)
|
||
}
|
||
return -7.110 - 0.00084*uranusEffectiveSubLatitude(jde, inst) + phase + distance
|
||
case 7:
|
||
year := 2000 + (jde-2451545)/365.25
|
||
unit := -7.00
|
||
switch {
|
||
case year < 1980:
|
||
unit = -6.89
|
||
case year <= 2000:
|
||
unit = -6.89 - 0.0054*(year-1980)
|
||
}
|
||
if a > 1.9 && year > 2000 {
|
||
unit += a * (7.944e-3 + 9.617e-5*a)
|
||
}
|
||
return unit + distance
|
||
}
|
||
return math.NaN()
|
||
}
|
||
|
||
// uranusEffectiveSubLatitude 天王星星下点与日下点行星面纬度绝对值的平均(度)。
|
||
func uranusEffectiveSubLatitude(jde float64, inst *Instance) float64 {
|
||
pole := eclipticUnitFromEquatorial(uranusPoleRA, uranusPoleDec)
|
||
geoLon, geoLat := planetApparentLoBoWithInstance(6, jde, inst)
|
||
helioLon, helioLat := planetLWithInstance(6, jde, inst), planetBWithInstance(6, jde, inst)
|
||
sub := func(lon, lat float64) float64 {
|
||
d := sphericalUnit(lon, lat)
|
||
// 星下点方向自行星指向观测者,与视方向相反。
|
||
centric := math.Asin(math.Max(-1, math.Min(1, -(pole[0]*d[0]+pole[1]*d[1]+pole[2]*d[2]))))
|
||
graphic := math.Atan(math.Tan(centric) / ((1 - uranusFlattening) * (1 - uranusFlattening)))
|
||
return math.Abs(graphic) * 180 / math.Pi
|
||
}
|
||
return (sub(geoLon, geoLat) + sub(helioLon, helioLat)) / 2
|
||
}
|
||
|
||
func sphericalUnit(lonDeg, latDeg float64) [3]float64 {
|
||
lon, lat := lonDeg*rad, latDeg*rad
|
||
return [3]float64{math.Cos(lat) * math.Cos(lon), math.Cos(lat) * math.Sin(lon), math.Sin(lat)}
|
||
}
|
||
|
||
func eclipticUnitFromEquatorial(raDeg, decDeg float64) [3]float64 {
|
||
v := sphericalUnit(raDeg, decDeg)
|
||
s, c := math.Sincos(j2000ObliquityDeg * rad)
|
||
return [3]float64{v[0], v[1]*c + v[2]*s, -v[1]*s + v[2]*c}
|
||
}
|
||
|
||
// MercuryMag2018WithInstance 水星视星等(Mallama & Hilton 2018)/ Mercury magnitude, Mallama & Hilton 2018.
|
||
func MercuryMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(1, jde, inst)
|
||
}
|
||
|
||
// VenusMag2018WithInstance 金星视星等(Mallama & Hilton 2018)/ Venus magnitude, Mallama & Hilton 2018.
|
||
func VenusMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(2, jde, inst)
|
||
}
|
||
|
||
// MarsMag2018WithInstance 火星视星等(Mallama & Hilton 2018,含自转与季节修正)/ Mars magnitude, Mallama & Hilton 2018 with rotation and season terms.
|
||
func MarsMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(3, jde, inst)
|
||
}
|
||
|
||
// JupiterMag2018WithInstance 木星视星等(Mallama & Hilton 2018)/ Jupiter magnitude, Mallama & Hilton 2018.
|
||
func JupiterMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(4, jde, inst)
|
||
}
|
||
|
||
// SaturnMag2018WithInstance 土星视星等(Mallama & Hilton 2018,含环)/ Saturn magnitude with rings, Mallama & Hilton 2018.
|
||
func SaturnMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(5, jde, inst)
|
||
}
|
||
|
||
// UranusMag2018WithInstance 天王星视星等(Mallama & Hilton 2018)/ Uranus magnitude, Mallama & Hilton 2018.
|
||
func UranusMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(6, jde, inst)
|
||
}
|
||
|
||
// NeptuneMag2018WithInstance 海王星视星等(Mallama & Hilton 2018)/ Neptune magnitude, Mallama & Hilton 2018.
|
||
func NeptuneMag2018WithInstance(jde float64, inst *Instance) float64 {
|
||
return planetMagnitude2018(7, jde, inst)
|
||
}
|
||
|
||
// 火星自转(有效中央经线,0°..390° 每 10°,首两项为 −20°、−10°)与季节(Ls)星等修正表。
|
||
var (
|
||
marsRotationCorrection = [40]float64{
|
||
0.024, 0.034, 0.036, 0.045, 0.038, 0.023, 0.015, 0.011,
|
||
0.000, -0.012, -0.018, -0.036, -0.044, -0.059, -0.060, -0.055,
|
||
-0.043, -0.041, -0.041, -0.036, -0.036, -0.018, -0.038, -0.011,
|
||
0.002, 0.004, 0.018, 0.019, 0.035, 0.050, 0.035, 0.027,
|
||
0.037, 0.048, 0.025, 0.022, 0.024, 0.034, 0.036, 0.045,
|
||
}
|
||
marsSeasonCorrection = [40]float64{
|
||
-0.030, -0.017, -0.029, -0.017, -0.014, -0.006, -0.018, -0.020,
|
||
-0.014, -0.030, -0.008, -0.040, -0.024, -0.037, -0.036, -0.032,
|
||
0.010, 0.010, -0.001, 0.044, 0.025, -0.004, -0.016, -0.008,
|
||
0.029, -0.054, -0.033, 0.055, 0.017, 0.052, 0.006, 0.087,
|
||
0.006, 0.064, 0.030, 0.019, -0.030, -0.017, -0.029, -0.017,
|
||
}
|
||
)
|
||
|
||
// marsStirling 四阶 Stirling 插值;angle 取 [0, 360),表中 angle=10k 对应下标 k+2。
|
||
func marsStirling(table *[40]float64, angle float64) float64 {
|
||
angle = math.Mod(angle, 360)
|
||
if angle < 0 {
|
||
angle += 360
|
||
}
|
||
zero := int(angle / 10)
|
||
p := angle/10 - float64(zero)
|
||
var d1 [3]float64
|
||
for i := range d1 {
|
||
d1[i] = table[zero+i+1] - table[zero+i]
|
||
}
|
||
d2 := [2]float64{d1[1] - d1[0], d1[2] - d1[1]}
|
||
// 四阶差分需要第 4 个一阶差分,表首尾各补两项即为此预留。
|
||
d1b := table[zero+4] - table[zero+3]
|
||
d2c := d1b - d1[2]
|
||
d3 := [2]float64{d2[1] - d2[0], d2c - d2[1]}
|
||
d4 := d3[1] - d3[0]
|
||
a4 := d4 / 24
|
||
a3 := (d3[0] + d3[1]) / 12
|
||
a2 := d2[1]/2 - a4
|
||
a1 := (d1[1]+d1[2])/2 - a3
|
||
a0 := table[zero+2]
|
||
return a0 + p*(a1+p*(a2+p*(a3+p*a4)))
|
||
}
|
||
|
||
// marsMagnitude2018 火星视星等:r、delta 为 AU,alpha 为相位角(度),子地、子日经度为西经(度),helioLon 为日心黄经(度)。
|
||
func marsMagnitude2018(r, delta, alpha, subEarthLon, subSunLon, helioLon float64) float64 {
|
||
distance := 5 * math.Log10(r*delta)
|
||
base := -0.367 + alpha*(-0.02573+0.0003445*alpha)
|
||
if alpha <= 50 {
|
||
base = -1.601 + alpha*(0.02267-0.0001302*alpha)
|
||
}
|
||
cm := (subEarthLon + subSunLon) / 2
|
||
if math.Abs(subEarthLon-subSunLon) > 180 {
|
||
cm += 180
|
||
}
|
||
// Ls 由日心黄经平移 −85° 得到。
|
||
return base + distance + marsStirling(&marsRotationCorrection, cm) + marsStirling(&marsSeasonCorrection, helioLon-85)
|
||
}
|