feat: 引入可切换星历模型并扩展天象观测链路
- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算 - 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询 - 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出 - 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解 - 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤 - 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持 - 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理 - 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"b612.me/astro/internal/ephem"
|
||||
. "b612.me/astro/tools"
|
||||
)
|
||||
|
||||
// topocentricHourAngleDec 由地心视赤经、视赤纬(度)与地心距(AU)给出观测者处的站心时角与站心视赤纬(度)。
|
||||
// 恒星时只算一次,视差修正与时角共用;观测者取海拔 0,海拔对太阳系天体视差的影响可忽略。
|
||||
func topocentricHourAngleDec(utcJD, lon, lat, ra, dec, distanceAU float64) (hourAngle, topocentricDec float64) {
|
||||
gast := ApparentSiderealTime(UTC2UT1(utcJD)) * 15
|
||||
topocentricRA, topocentricDec := topocentricRaDecWithSidereal(ra, dec, lat, lon, gast, distanceAU, 0)
|
||||
return Limit360(gast + lon - topocentricRA), topocentricDec
|
||||
}
|
||||
|
||||
// horizontalAltitude 时角、赤纬、纬度(度)转高度角 / altitude from hour angle, declination and latitude.
|
||||
func horizontalAltitude(hourAngle, dec, lat float64) float64 {
|
||||
return ArcSin(Sin(lat)*Sin(dec) + Cos(dec)*Cos(lat)*Cos(hourAngle))
|
||||
}
|
||||
|
||||
// horizontalAzimuth 时角、赤纬、纬度(度)转方位角,北起向东 / azimuth from north through east.
|
||||
func horizontalAzimuth(hourAngle, dec, lat float64) float64 {
|
||||
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
|
||||
}
|
||||
|
||||
// planetApparentRaDecDistanceNWithInstance 行星地心视赤经、视赤纬与几何地心距,三者取自同一次求值。
|
||||
func planetApparentRaDecDistanceNWithInstance(index int, jde float64, n int, inst *Instance) (ra, dec, distanceAU float64) {
|
||||
geo, _, distanceAU, ok := planetApparentPositionWithInstance(index, jde, n, inst)
|
||||
if !ok || math.IsNaN(geo.lo) || math.IsNaN(geo.bo) {
|
||||
return math.NaN(), math.NaN(), math.NaN()
|
||||
}
|
||||
ra, dec = planetApparentRaDecFromLoBo(jde, geo.lo, geo.bo)
|
||||
return ra, dec, distanceAU
|
||||
}
|
||||
|
||||
func planetTopocentricHourAngleDecN(index int, localJD, lon, lat, timezone float64, n int, inst *Instance) (float64, float64) {
|
||||
utcJD := localJD - timezone/24.0
|
||||
ra, dec, distanceAU := planetApparentRaDecDistanceNWithInstance(index, UTC2TT(utcJD), n, inst)
|
||||
return topocentricHourAngleDec(utcJD, lon, lat, ra, dec, distanceAU)
|
||||
}
|
||||
|
||||
// planetHeightN 行星站心视高度角(度,不含折射)/ topocentric planet altitude without refraction.
|
||||
func planetHeightN(index int, localJD, lon, lat, timezone float64, n int, inst *Instance) float64 {
|
||||
hourAngle, dec := planetTopocentricHourAngleDecN(index, localJD, lon, lat, timezone, n, inst)
|
||||
return horizontalAltitude(hourAngle, dec, lat)
|
||||
}
|
||||
|
||||
// planetAzimuthN 行星站心方位角(度)/ topocentric planet azimuth.
|
||||
func planetAzimuthN(index int, localJD, lon, lat, timezone float64, n int, inst *Instance) float64 {
|
||||
hourAngle, dec := planetTopocentricHourAngleDecN(index, localJD, lon, lat, timezone, n, inst)
|
||||
return horizontalAzimuth(hourAngle, dec, lat)
|
||||
}
|
||||
|
||||
// sunTopocentricHourAngleDecN 太阳站心时角、站心视赤纬与地日距 / topocentric solar hour angle, declination and distance.
|
||||
func sunTopocentricHourAngleDecN(jd, lon, lat, tz float64, n int, inst *Instance) (hourAngle, dec, distanceAU float64) {
|
||||
utcJD := jd - tz/24.0
|
||||
ra, dec, distanceAU := hSunApparentRaDecDistanceN(UTC2TT(utcJD), n, inst)
|
||||
hourAngle, dec = topocentricHourAngleDec(utcJD, lon, lat, ra, dec, distanceAU)
|
||||
return hourAngle, dec, distanceAU
|
||||
}
|
||||
|
||||
// sunAzimuthN 地距只用于视差,矢量视位置可用时直接取其距离,省去一次地距求值。
|
||||
func sunAzimuthN(jd, lon, lat, tz float64, n int, inst *Instance) float64 {
|
||||
utcJD := jd - tz/24.0
|
||||
tt := UTC2TT(utcJD)
|
||||
var ra, dec, distanceAU float64
|
||||
if lo, bo, _, dist, ok, err := vectorApparentWithInstance(ephem.Sun, tt, n, inst); err != nil {
|
||||
return math.NaN()
|
||||
} else if ok {
|
||||
ra, dec = LoBoToRaDec(tt, lo, bo)
|
||||
distanceAU = dist
|
||||
} else {
|
||||
ra, dec, distanceAU = hSunApparentRaDecDistanceN(tt, n, inst)
|
||||
}
|
||||
hourAngle, topocentricDec := topocentricHourAngleDec(utcJD, lon, lat, ra, dec, distanceAU)
|
||||
return horizontalAzimuth(hourAngle, topocentricDec, lat)
|
||||
}
|
||||
Reference in New Issue
Block a user