You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
astro/basic/star.go

173 lines
5.1 KiB
Go

5 years ago
package basic
import (
. "b612.me/astro/tools"
"math"
5 years ago
)
3 years ago
// StarHeight 星体的高度角
// 传入 jde时间、瞬时赤经、瞬时赤纬、经度、纬度、时区jde时间应为时区时间
// 返回高度角,单位为度
func StarHeight(jde, ra, dec, lon, lat, timezone float64) float64 {
// 转换为世界时
utcJde := jde - timezone/24.0
// 计算视恒星时
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
3 years ago
// 计算时角
H := 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)
return ArcSin(sinHeight)
}
//StarAzimuth 星体的方位角
// 传入 jde时间、瞬时赤经、瞬时赤纬、经度、纬度、时区jde时间应为时区时间
// 返回方位角单位为度正北为0度数顺时针增加取值范围[0-360)
func StarAzimuth(jde, ra, dec, lon, lat, timezone float64) float64 {
// 转换为世界时
utcJde := jde - timezone/24.0
// 计算视恒星时
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
3 years ago
// 计算时角
H := 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
}
return Azimuth + 180
}
if H/15 < 12 {
return Azimuth + 180
}
return Azimuth
}
//StarHourAngle 星体的时角
// 传入 jde时间、瞬时赤经、瞬时赤纬、经度、时区jde时间应为时区时间
// 返回时角
func StarHourAngle(jde, ra, lon, timezone float64) float64 {
// 转换为世界时
utcJde := jde - timezone/24.0
// 计算视恒星时
st := Limit360(ApparentSiderealTime(utcJde)*15 + lon)
3 years ago
// 计算时角
return Limit360(st - ra)
}
// MeanSiderealTime 不含章动下的恒星时
func MeanSiderealTime(JD float64) float64 {
5 years ago
T := (JD - 2451545) / 36525
return (Limit360(280.46061837+360.98564736629*(JD-2451545.0)+0.000387933*T*T-T*T*T/38710000) / 15)
}
// ApparentSiderealTime 视恒星时,计算章动
func ApparentSiderealTime(JD float64) float64 {
tmp := MeanSiderealTime(JD)
5 years ago
return tmp + HJZD(JD)*Cos(Sita(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)
5 years ago
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 {
return StarRiseDownTime(jde, ra, dec, lon, lat, height, timezone, aero, true)
}
func StarDownTime(jde, ra, dec, lon, lat, height, timezone float64, aero bool) float64 {
return StarRiseDownTime(jde, ra, dec, lon, lat, height, timezone, aero, false)
}
5 years ago
func StarRiseDownTime(jde, ra, dec, lon, lat, height, timezone float64, aero, isRise bool) float64 {
//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)
sct := StarCulminationTime(jde, ra, lon, timezone)
tmp := (Sin(An) - 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 //极昼
}
}
var JD1 float64
if isRise {
JD1 = sct - ArcCos(tmp)/15.0/24.0
} else {
JD1 = 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 {
break
}
}
return JD1
}
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
limitStarHA := func(jde, ra, lon, timezone float64) float64 {
ha := StarHourAngle(jde, ra, lon, timezone)
if ha < 180 {
ha += 360
}
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 {
break
}
}
return JD1
5 years ago
}
func StarAngularSeparation(ra1, dec1, ra2, dec2 float64) float64 {
//cos(d)=sinδ1 sinδ2 + cosδ1 cosδ2 cos(α1-α2)
d := Sin(dec1)*Sin(dec2) + Cos(dec1)*Cos(dec2)*Cos(ra1-ra2)
if math.Abs(d) >= 0.999999997 {
//d = √(Δα*cosδ)2+(Δδ)2
tmp1 := ((ra1 - ra2) * Cos((dec1+dec2)/2))
tmp2 := (dec1 - dec2)
return math.Sqrt(tmp1*tmp1 + tmp2*tmp2)
}
return ArcCos(d)
}