feat: 扩展天文计算能力
- 新增日食、月食、本地可见性、中心线、半影区域、SVG 图示与沙罗周期信息 - 新增行星冲合、留、方照、物理星历、视直径、相位、亮肢角、轨道节点等计算 - 新增木星伽利略卫星位置、现象与接触事件计算 - 新增恒星星表、星座判定、自行修正与观测辅助能力 - 新增 coord、formula、orbit、sundial、lite/sun、lite/moon 等扩展包 - 完善农历年号、月相英文别名、视差角、大气质量、折射、日晷与双星计算 - 增加 NASA、JPL Horizons、IMCCE 等回归测试数据与基线测试 - 重构基础算法文件组织,补充大量公开 API 注释和语义回归测试 - 更新中文和英文 README,补充示例、精度说明、SVG 配图
This commit is contained in:
+51
-78
@@ -14,10 +14,10 @@ func StarHeight(jde, ra, dec, lon, lat, timezone float64) float64 {
|
||||
// 计算视恒星时
|
||||
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
|
||||
// 计算时角
|
||||
H := Limit360(st - ra)
|
||||
hourAngle := Limit360(st - ra)
|
||||
// 高度角、时角与天球座标三角转换公式
|
||||
// sin(h)=sin(lat)*sin(dec)+cos(dec)*cos(lat)*cos(H)
|
||||
sinHeight := Sin(lat)*Sin(dec) + Cos(dec)*Cos(lat)*Cos(H)
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -30,20 +30,20 @@ func StarAzimuth(jde, ra, dec, lon, lat, timezone float64) float64 {
|
||||
// 计算视恒星时
|
||||
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
|
||||
// 计算时角
|
||||
H := Limit360(st - ra)
|
||||
hourAngle := Limit360(st - ra)
|
||||
// 三角转换公式
|
||||
tanAzimuth := Sin(H) / (Cos(H)*Sin(lat) - Tan(dec)*Cos(lat))
|
||||
Azimuth := ArcTan(tanAzimuth)
|
||||
if Azimuth < 0 {
|
||||
if H/15 < 12 {
|
||||
return Azimuth + 360
|
||||
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
|
||||
return azimuth + 180
|
||||
}
|
||||
if H/15 < 12 {
|
||||
return Azimuth + 180
|
||||
if hourAngle/15 < 12 {
|
||||
return azimuth + 180
|
||||
}
|
||||
return Azimuth
|
||||
return azimuth
|
||||
}
|
||||
|
||||
// StarHourAngle 星体的时角
|
||||
@@ -59,25 +59,25 @@ func StarHourAngle(jde, ra, lon, timezone float64) float64 {
|
||||
}
|
||||
|
||||
// MeanSiderealTime 平恒星时
|
||||
func MeanSiderealTime(JD float64) float64 {
|
||||
return MeanSiderealTime2006(JD)
|
||||
func MeanSiderealTime(jd float64) float64 {
|
||||
return MeanSiderealTime2006(jd)
|
||||
}
|
||||
|
||||
// ApparentSiderealTime 视恒星时,计算章动
|
||||
func ApparentSiderealTime(JD float64) float64 {
|
||||
return ApparentSiderealTime2006(JD)
|
||||
func ApparentSiderealTime(jd float64) float64 {
|
||||
return ApparentSiderealTime2006(jd)
|
||||
}
|
||||
|
||||
// MeanSiderealTime1982 不含章动下的恒星时
|
||||
func MeanSiderealTime1982(JD float64) float64 {
|
||||
T := (JD - 2451545) / 36525
|
||||
return (Limit360(280.46061837+360.98564736629*(JD-2451545.0)+0.000387933*T*T-T*T*T/38710000) / 15)
|
||||
func MeanSiderealTime1982(jd float64) float64 {
|
||||
t := (jd - 2451545) / 36525
|
||||
return (Limit360(280.46061837+360.98564736629*(jd-2451545.0)+0.000387933*t*t-t*t*t/38710000) / 15)
|
||||
}
|
||||
|
||||
// ApparentSiderealTime1982 视恒星时,计算章动
|
||||
func ApparentSiderealTime1982(JD float64) float64 {
|
||||
tmp := MeanSiderealTime1982(JD)
|
||||
return tmp + Nutation2000Bi(JD)*Cos(Sita(JD))/15
|
||||
func ApparentSiderealTime1982(jd float64) float64 {
|
||||
tmp := MeanSiderealTime1982(jd)
|
||||
return tmp + Nutation2000Bi(jd)*Cos(TrueObliquity(jd))/15
|
||||
}
|
||||
|
||||
// EarthRotationAngle 计算地球自转角 (ERA)
|
||||
@@ -116,82 +116,55 @@ func MeanSiderealTime2006(jd_ut1 float64) float64 {
|
||||
}
|
||||
|
||||
// ApparentSiderealTime2006 视恒星时,计算章动
|
||||
func ApparentSiderealTime2006(JD float64) float64 {
|
||||
tmp := MeanSiderealTime2006(JD)
|
||||
return tmp + Nutation2000Bi(JD)*Cos(Sita(JD))/15
|
||||
func ApparentSiderealTime2006(jd float64) float64 {
|
||||
tmp := MeanSiderealTime2006(jd)
|
||||
return tmp + Nutation2000Bi(jd)*Cos(TrueObliquity(jd))/15
|
||||
}
|
||||
|
||||
func StarAngle(RA, DEC, JD, Lon, Lat, TZ float64) float64 {
|
||||
//JD=JD-8/24+TZ/24;
|
||||
calcjd := JD - TZ/24
|
||||
st := Limit360(ApparentSiderealTime(calcjd)*15 + Lon)
|
||||
H := Limit360(st - RA)
|
||||
tmp2 := Sin(H) / (Cos(H)*Sin(Lat) - Tan(DEC)*Cos(Lat))
|
||||
Angle := ArcTan(tmp2)
|
||||
if Angle < 0 {
|
||||
if H/15 < 12 {
|
||||
return Angle + 360
|
||||
} else {
|
||||
return Angle + 180
|
||||
}
|
||||
} else {
|
||||
if H/15 < 12 {
|
||||
return Angle + 180
|
||||
} else {
|
||||
return Angle
|
||||
}
|
||||
}
|
||||
func StarRiseTime(jde, ra, dec, lon, lat, height, timezone float64, aero bool) (float64, error) {
|
||||
return StarRiseSetTime(jde, ra, dec, lon, lat, height, timezone, aero, true)
|
||||
}
|
||||
|
||||
func StarRiseTime(jde, ra, dec, lon, lat, height, timezone float64, aero bool) float64 {
|
||||
return StarRiseDownTime(jde, ra, dec, lon, lat, height, timezone, aero, true)
|
||||
func StarSetTime(jde, ra, dec, lon, lat, height, timezone float64, aero bool) (float64, error) {
|
||||
return StarRiseSetTime(jde, ra, dec, lon, lat, height, timezone, aero, false)
|
||||
}
|
||||
|
||||
func StarDownTime(jde, ra, dec, lon, lat, height, timezone float64, aero bool) float64 {
|
||||
return StarRiseDownTime(jde, ra, dec, lon, lat, height, timezone, aero, false)
|
||||
}
|
||||
|
||||
func StarRiseDownTime(jde, ra, dec, lon, lat, height, timezone float64, aero, isRise bool) float64 {
|
||||
func StarRiseSetTime(jde, ra, dec, lon, lat, height, timezone float64, aero, isRise bool) (float64, error) {
|
||||
//jde 世界时,非力学时,当地时区 0时,无需转换力学时
|
||||
//ra,dec 瞬时天球座标,非J2000等时间天球坐标
|
||||
jde = math.Floor(jde) + 0.5
|
||||
var An float64 = 0
|
||||
if aero {
|
||||
An = -0.566667
|
||||
}
|
||||
An = An - HeightDegreeByLat(height, lat)
|
||||
targetAltitude := StandardAltitudeStar(aero, height, lat)
|
||||
sct := StarCulminationTime(jde, ra, lon, timezone)
|
||||
tmp := (Sin(An) - Sin(dec)*Sin(lat)) / (Cos(dec) * Cos(lat))
|
||||
tmp := (Sin(targetAltitude) - Sin(dec)*Sin(lat)) / (Cos(dec) * Cos(lat))
|
||||
if math.Abs(tmp) > 1 {
|
||||
if StarHeight(sct, ra, dec, lon, lat, timezone) < 0 {
|
||||
return -2 //极夜
|
||||
} else {
|
||||
return -1 //极昼
|
||||
return 0, ErrNeverRise
|
||||
}
|
||||
return 0, ErrNeverSet
|
||||
}
|
||||
var JD1 float64
|
||||
var estimateJD float64
|
||||
if isRise {
|
||||
JD1 = sct - ArcCos(tmp)/15.0/24.0
|
||||
estimateJD = sct - ArcCos(tmp)/15.0/24.0
|
||||
} else {
|
||||
JD1 = sct + ArcCos(tmp)/15.0/24.0
|
||||
estimateJD = sct + ArcCos(tmp)/15.0/24.0
|
||||
}
|
||||
for {
|
||||
JD0 := JD1
|
||||
stDegree := StarHeight(JD0, ra, dec, lon, lat, timezone) - An
|
||||
stDegreep := (StarHeight(JD0+0.000005, ra, dec, lon, lat, timezone) - StarHeight(JD0-0.000005, ra, dec, lon, lat, timezone)) / 0.00001
|
||||
JD1 = JD0 - stDegree/stDegreep
|
||||
if math.Abs(JD1-JD0) <= 0.00001 {
|
||||
prevJD := estimateJD
|
||||
stDegree := StarHeight(prevJD, ra, dec, lon, lat, timezone) - targetAltitude
|
||||
stDegreep := (StarHeight(prevJD+0.000005, ra, dec, lon, lat, timezone) - StarHeight(prevJD-0.000005, ra, dec, lon, lat, timezone)) / 0.00001
|
||||
estimateJD = prevJD - stDegree/stDegreep
|
||||
if math.Abs(estimateJD-prevJD) <= 0.00001 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return JD1
|
||||
return estimateJD, nil
|
||||
}
|
||||
|
||||
func StarCulminationTime(jde, ra, lon, timezone float64) float64 {
|
||||
//jde 世界时,非力学时,当地时区 0时,无需转换力学时
|
||||
//ra,dec 瞬时天球座标,非J2000等时间天球坐标
|
||||
jde = math.Floor(jde) + 0.5
|
||||
JD1 := jde + Limit360(360-StarHourAngle(jde, ra, lon, timezone))/15.0/24.0*0.99726851851851851851
|
||||
estimateJD := jde + Limit360(360-StarHourAngle(jde, ra, lon, timezone))/15.0/24.0*0.99726851851851851851
|
||||
limitStarHA := func(jde, ra, lon, timezone float64) float64 {
|
||||
ha := StarHourAngle(jde, ra, lon, timezone)
|
||||
if ha < 180 {
|
||||
@@ -200,15 +173,15 @@ func StarCulminationTime(jde, ra, lon, timezone float64) float64 {
|
||||
return ha
|
||||
}
|
||||
for {
|
||||
JD0 := JD1
|
||||
stDegree := limitStarHA(JD0, ra, lon, timezone) - 360
|
||||
stDegreep := (limitStarHA(JD0+0.000005, ra, lon, timezone) - limitStarHA(JD0-0.000005, ra, lon, timezone)) / 0.00001
|
||||
JD1 = JD0 - stDegree/stDegreep
|
||||
if math.Abs(JD1-JD0) <= 0.00001 {
|
||||
prevJD := estimateJD
|
||||
stDegree := limitStarHA(prevJD, ra, lon, timezone) - 360
|
||||
stDegreep := (limitStarHA(prevJD+0.000005, ra, lon, timezone) - limitStarHA(prevJD-0.000005, ra, lon, timezone)) / 0.00001
|
||||
estimateJD = prevJD - stDegree/stDegreep
|
||||
if math.Abs(estimateJD-prevJD) <= 0.00001 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return JD1
|
||||
return estimateJD
|
||||
}
|
||||
|
||||
func StarAngularSeparation(ra1, dec1, ra2, dec2 float64) float64 {
|
||||
|
||||
Reference in New Issue
Block a user