feat: 完善时标与天象几何计算并扩展输出接口
- 新增时标、ΔT 模型、质心时间与 UT1 支持 - 改进日月食、月掩、行星事件及路径边界计算 - 完善恒星三维自行与动态距离传播 - 扩展 SVG、GeoJSON、KML 输出与底层距离换算工具 - 整理中英文手册、示例资源及回归测试
This commit is contained in:
+55
-5
@@ -252,9 +252,38 @@ func StarDataByHR(hr int) (StarData, error) {
|
||||
return cachedStarData[hr-1], nil
|
||||
}
|
||||
|
||||
// RaDecByJde 按 TT 儒略日归算恒星位置,单位为度 / star position in degrees for a TT Julian date.
|
||||
// Pc>0 时按三维空间运动推进(自行 + RadVel),否则退回只推进角分量的二维。
|
||||
// With Pc>0 the position advances in three dimensions (proper motion plus radial velocity); otherwise only the angular components advance.
|
||||
func (s InnerStarData) RaDecByJde(jde float64) (float64, float64) {
|
||||
// BSC 的 pmRA 是投影自行 cos(Dec)*dRA/dt,而不是 dRA/dt / BSC pmRA is the projected motion cos(Dec)*dRA/dt, not dRA/dt.
|
||||
year := ((jde - 2451545.0) / 365.2422)
|
||||
if s.distanceAU() > 0 {
|
||||
return s.raDecByJde3D(jde)
|
||||
}
|
||||
return s.raDecByJde2D(jde)
|
||||
}
|
||||
|
||||
// RaDecByDate 按给定时刻归算恒星位置,单位为度 / star position in degrees at the given instant.
|
||||
// 传入时刻按 UTC 解释并换算成 TT 儒略日,与 RaDecByJde 同口径。
|
||||
// The instant is read as UTC and converted to a TT Julian date, the same convention as RaDecByJde.
|
||||
func (s StarData) RaDecByDate(date time.Time) (float64, float64) {
|
||||
// 星表历元与岁差都按 TT 度量,自行归算的历元差必须用 TT 儒略日。
|
||||
jde := UTC2TT(Date2JD(date.UTC()))
|
||||
return s.RaDecByJde(jde)
|
||||
}
|
||||
|
||||
func (s InnerStarData) distanceAU() float64 {
|
||||
if s.Pc <= 0 {
|
||||
return 0
|
||||
}
|
||||
// 秒差距到天文单位:648000/π 为定义值。
|
||||
return s.Pc * 648000 / math.Pi
|
||||
}
|
||||
|
||||
// raDecByJde2D 只推进赤经赤纬两个角分量,等价于把恒星当作无穷远。
|
||||
func (s InnerStarData) raDecByJde2D(jde float64) (float64, float64) {
|
||||
// 自行按儒略年计:J2000 是儒略历元,年长 365.25 日而非回归年。
|
||||
// pmRA 是投影自行 cos(Dec)*dRA/dt,不是 dRA/dt。
|
||||
year := (jde - 2451545.0) / 365.25
|
||||
dec := s.Dec + year*s.PmDec/3600
|
||||
cosDec := math.Cos(s.Dec * math.Pi / 180)
|
||||
ra := s.Ra
|
||||
@@ -264,7 +293,28 @@ func (s InnerStarData) RaDecByJde(jde float64) (float64, float64) {
|
||||
return Precess(ra, dec, 2451545.0, jde)
|
||||
}
|
||||
|
||||
func (s StarData) RaDecByDate(date time.Time) (float64, float64) {
|
||||
jde := Date2JDE(date.UTC())
|
||||
return s.RaDecByJde(jde)
|
||||
// raDecByJde3D 按三维匀速直线运动推进位置矢量,赤经赤纬只是其方向。
|
||||
func (s InnerStarData) raDecByJde3D(jde float64) (float64, float64) {
|
||||
year := (jde - 2451545.0) / 365.25
|
||||
raRad := s.Ra * math.Pi / 180
|
||||
decRad := s.Dec * math.Pi / 180
|
||||
sinDec, cosDec := math.Sin(decRad), math.Cos(decRad)
|
||||
distance := s.distanceAU()
|
||||
// 切向速度 AU/年 = 角速度(rad/年) × 距离;径向速度 km/s 换算为 AU/年。
|
||||
pmRA := s.PmRA * math.Pi / (180 * 3600) * distance
|
||||
pmDec := s.PmDec * math.Pi / (180 * 3600) * distance
|
||||
radial := s.RadVel * 365.25 * 86400 / 149597870.7
|
||||
cosRA, sinRA := math.Cos(raRad), math.Sin(raRad)
|
||||
position := [3]float64{
|
||||
distance*cosDec*cosRA + year*(pmDec*(-sinDec*cosRA)-pmRA*sinRA+radial*cosDec*cosRA),
|
||||
distance*cosDec*sinRA + year*(pmDec*(-sinDec*sinRA)+pmRA*cosRA+radial*cosDec*sinRA),
|
||||
distance*sinDec + year*(pmDec*cosDec+radial*sinDec),
|
||||
}
|
||||
norm := math.Sqrt(position[0]*position[0] + position[1]*position[1] + position[2]*position[2])
|
||||
ra := math.Atan2(position[1], position[0]) * 180 / math.Pi
|
||||
if ra < 0 {
|
||||
ra += 360
|
||||
}
|
||||
dec := math.Asin(position[2]/norm) * 180 / math.Pi
|
||||
return Precess(ra, dec, 2451545.0, jde)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user