Files
astro/coord/coord.go
T
b612 044f2f4381 feat: 引入可切换星历模型并扩展天象观测链路
- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算
- 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询
- 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出
- 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解
- 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤
- 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持
- 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理
- 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
2026-10-15 23:54:15 +08:00

144 lines
6.1 KiB
Go

// Package coord 坐标工具包 / coordinate utility package.
//
// 本包面向用户提供常用坐标变换、恒星时、岁差、站心和地平坐标封装。
// 所有角度输入和输出默认使用度;恒星时输出使用小时。
// date 按绝对时刻使用,内部会转换为 UTC 后计算。
package coord
import (
"time"
"b612.me/astro/basic"
)
// Ecliptic 黄道坐标 / ecliptic coordinates.
type Ecliptic struct {
Lon float64 // 黄经,单位度 / ecliptic longitude in degrees.
Lat float64 // 黄纬,单位度 / ecliptic latitude in degrees.
}
// Equatorial 赤道坐标 / equatorial coordinates.
type Equatorial struct {
RA float64 // 赤经,单位度 / right ascension in degrees.
Dec float64 // 赤纬,单位度 / declination in degrees.
}
// Horizontal 地平坐标 / horizontal coordinates.
type Horizontal struct {
Azimuth float64 // 方位角,正北为0,顺时针增加 / azimuth from north clockwise, degrees.
Altitude float64 // 高度角,单位度 / altitude in degrees.
Zenith float64 // 天顶距,单位度 / zenith distance in degrees.
HourAngle float64 // 时角,单位度 / hour angle in degrees.
}
// jdUTC 绝对时刻换算成 UTC 民用儒略日,本包所有入口共用这一个口径。
//
// 黄赤交角、章动与岁差按 TT 取用,这里给的是 UTC 民用 JD:两者的差比本包例程约 0.1″
// 的精度低三个数量级,故不叠加 UTC2TT。
func jdUTC(date time.Time) float64 {
return basic.Date2JD(date.UTC())
}
// EclipticToEquatorial 黄道坐标转赤道坐标 / converts ecliptic to equatorial coordinates.
func EclipticToEquatorial(date time.Time, lon, lat float64) Equatorial {
ra, dec := basic.LoBoToRaDec(jdUTC(date), lon, lat)
return Equatorial{RA: ra, Dec: dec}
}
// EquatorialToEcliptic 赤道坐标转黄道坐标 / converts equatorial to ecliptic coordinates.
func EquatorialToEcliptic(date time.Time, ra, dec float64) Ecliptic {
lon, lat := basic.RaDecToLoBo(jdUTC(date), ra, dec)
return Ecliptic{Lon: lon, Lat: lat}
}
// Precess 岁差修正 / precesses equatorial coordinates from one date to another.
func Precess(from, to time.Time, ra, dec float64) Equatorial {
nextRA, nextDec := basic.Precess(ra, dec, jdUTC(from), jdUTC(to))
return Equatorial{RA: nextRA, Dec: nextDec}
}
// EclipticObliquity 黄赤交角 / ecliptic obliquity.
func EclipticObliquity(date time.Time, nutation bool) float64 {
return basic.EclipticObliquity(jdUTC(date), nutation)
}
// Nutation2000B IAU 2000B 章动 / IAU 2000B nutation.
func Nutation2000B(date time.Time) (longitude, obliquity float64) {
return basic.Nutation2000B(jdUTC(date))
}
// Nutation2000A IAU 2000A 章动,度;仅显式调用时使用,默认链路仍为 2000B / IAU 2000A nutation, opt-in.
func Nutation2000A(date time.Time) (longitude, obliquity float64) {
return basic.Nutation2000A(jdUTC(date))
}
// MeanObliquity2006 IAU 2006 平黄赤交角,度 / IAU 2006 mean obliquity in degrees.
func MeanObliquity2006(date time.Time) float64 {
return basic.MeanObliquity2006(jdUTC(date))
}
// Nutation1980 IAU 1980 章动 / IAU 1980 nutation.
func Nutation1980(date time.Time) (longitude, obliquity float64) {
return basic.Nutation1980(jdUTC(date))
}
// MeanSiderealTime 平恒星时,单位小时 / mean sidereal time in hours.
func MeanSiderealTime(date time.Time) float64 {
return basic.MeanSiderealTime(basic.UTC2UT1(jdUTC(date)))
}
// ApparentSiderealTime 真恒星时,单位小时 / apparent sidereal time in hours.
func ApparentSiderealTime(date time.Time) float64 {
return basic.ApparentSiderealTime(basic.UTC2UT1(jdUTC(date)))
}
// HourAngle 时角 / hour angle.
//
// ra 为瞬时赤经;observerLon 为观测者经度,东正西负。
// ra is apparent right ascension; observerLon is east-positive longitude.
func HourAngle(date time.Time, ra, observerLon float64) float64 {
return basic.StarHourAngle(jdUTC(date), ra, observerLon, 0)
}
// EquatorialToHorizontal 赤道坐标转地平坐标 / converts equatorial to horizontal coordinates.
//
// ra/dec 为瞬时赤经赤纬;observerLon/observerLat 为观测者经纬度,东正西负、北正南负。
// ra/dec are apparent coordinates; observerLon/observerLat are east-positive and north-positive.
func EquatorialToHorizontal(date time.Time, ra, dec, observerLon, observerLat float64) Horizontal {
jd := jdUTC(date)
altitude := basic.StarHeight(jd, ra, dec, observerLon, observerLat, 0)
return Horizontal{
Azimuth: basic.StarAzimuth(jd, ra, dec, observerLon, observerLat, 0),
Altitude: altitude,
Zenith: 90 - altitude,
HourAngle: basic.StarHourAngle(jd, ra, observerLon, 0),
}
}
// TopocentricEquatorial 地心赤道坐标转站心赤道坐标 / converts geocentric to topocentric equatorial coordinates.
//
// distanceAU 为目标天体到地心距离,单位 AU;height 为观测者椭球高(大地高),单位米。
// distanceAU is geocentric distance in AU; height is observer elevation in meters.
func TopocentricEquatorial(date time.Time, ra, dec, observerLon, observerLat, distanceAU, height float64) Equatorial {
topRA, topDec := basic.TopocentricRaDec(ra, dec, observerLat, observerLon, jdUTC(date), distanceAU, height)
return Equatorial{RA: topRA, Dec: topDec}
}
// TopocentricEcliptic 地心黄道坐标转站心黄道坐标 / converts geocentric to topocentric ecliptic coordinates.
//
// distanceAU 为目标天体到地心距离,单位 AU;height 为观测者椭球高(大地高),单位米。
// distanceAU is geocentric distance in AU; height is observer elevation in meters.
func TopocentricEcliptic(date time.Time, lon, lat, observerLon, observerLat, distanceAU, height float64) Ecliptic {
jd := jdUTC(date)
topLon, topLat := basic.TopocentricLoBo(lon, lat, observerLat, observerLon, jd, distanceAU, height)
return Ecliptic{Lon: topLon, Lat: topLat}
}
// AngularSeparation 角距离 / angular separation.
//
// 输入为两组赤道坐标,单位度;返回角距离,单位度。
// Inputs are two equatorial coordinates in degrees; return value is in degrees.
func AngularSeparation(ra1, dec1, ra2, dec2 float64) float64 {
return basic.StarAngularSeparation(ra1, dec1, ra2, dec2)
}