91 lines
4.0 KiB
Go
91 lines
4.0 KiB
Go
|
|
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)
|
||
|
|
}
|