// Times computes UT rise, transit and set times for a celestial object on // a day of interest. // // The function argurments do not actually include the day, but do include // a number of values computed from the day. // // p is geographic coordinates of observer. // ΔT is delta T. // h0 is "standard altitude" of the body. // Th0 is apparent sidereal time at 0h UT at Greenwich. // α3, δ3 are slices of three right ascensions and declinations. // // h0 unit is radians. // // Th0 must be the time on the day of interest, in seconds. // See sidereal.Apparent0UT. // // α3, δ3 must be values at 0h dynamical time for the day before, the day of, // and the day after the day of interest. Units are radians. // // Result units are seconds of day and are in the range [0,86400). func Times(p globe.Coord, ΔT unit.Time, h0 unit.Angle, Th0 unit.Time, α3 []unit.RA, δ3 []unit.Angle) (tRise, tTransit, tSet unit.Time, err error) { tRise, tTransit, tSet, err = ApproxTimes(p, h0, Th0, α3[1], δ3[1]) if err != nil { return } αf := make([]float64, 3) for i, α := range α3 { αf[i] = α.Rad() } δf := make([]float64, 3) for i, δ := range δ3 { δf[i] = δ.Rad() } var d3α, d3δ *interp.Len3 d3α, err = interp.NewLen3(-86400, 86400, αf) if err != nil { return } d3δ, err = interp.NewLen3(-86400, 86400, δf) if err != nil { return } // adjust tTransit { th0 := (Th0 + tTransit.Mul(360.985647/360)).Mod1() α := d3α.InterpolateX((tTransit + ΔT).Sec()) // local hour angle as Time H := th0 - unit.TimeFromRad(p.Lon.Rad()+α) tTransit -= H } // adjust tRise, tSet sLat, cLat := p.Lat.Sincos() adjustRS := func(m unit.Time) (unit.Time, error) { th0 := (Th0 + m.Mul(360.985647/360)).Mod1() ut := (m + ΔT).Sec() α := d3α.InterpolateX(ut) δ := d3δ.InterpolateX(ut) Hrad := th0.Rad() - p.Lon.Rad() - α sδ, cδ := math.Sincos(δ) sH, cH := math.Sincos(Hrad) h := math.Asin(sLat*sδ + cLat*cδ*cH) md := (unit.TimeFromRad(h) - h0.Time()).Div(cδ * cLat * sH) return m + md, nil } tRise, err = adjustRS(tRise) if err != nil { return } tSet, err = adjustRS(tSet) return }
// ApproxTimes computes approximate UT rise, transit and set times for // a celestial object on a day of interest. // // The function argurments do not actually include the day, but do include // values computed from the day. // // p is geographic coordinates of observer. // h0 is "standard altitude" of the body. // Th0 is apparent sidereal time at 0h UT at Greenwich. // α, δ are right ascension and declination of the body. // // Th0 must be the time on the day of interest. // See sidereal.Apparent0UT. // // α, δ must be values at 0h dynamical time for the day of interest. func ApproxTimes(p globe.Coord, h0 unit.Angle, Th0 unit.Time, α unit.RA, δ unit.Angle) (tRise, tTransit, tSet unit.Time, err error) { // approximate local hour angle sLat, cLat := p.Lat.Sincos() sδ1, cδ1 := δ.Sincos() cH0 := (h0.Sin() - sLat*sδ1) / (cLat * cδ1) // (15.1) p. 102 if cH0 < -1 || cH0 > 1 { err = ErrorCircumpolar return } H0 := unit.TimeFromRad(math.Acos(cH0)) // approximate transit, rise, set times. // (15.2) p. 102. mt := unit.TimeFromRad(α.Rad()+p.Lon.Rad()) - Th0 tTransit = mt.Mod1() tRise = (mt - H0).Mod1() tSet = (mt + H0).Mod1() return }