// Topocentric2 returns topocentric corrections including parallax. // // This function implements the "non-rigorous" method descripted in the text. // // Note that results are corrections, not corrected coordinates. func Topocentric2(α unit.RA, δ unit.Angle, Δ, ρsφʹ, ρcφʹ float64, L unit.Angle, jde float64) (Δα unit.HourAngle, Δδ unit.Angle) { π := Horizontal(Δ) θ0 := sidereal.Apparent(jde) H := (θ0.Angle() - L - unit.Angle(α)).Mod1() sH, cH := H.Sincos() sδ, cδ := δ.Sincos() Δα = unit.HourAngle(-π.Mul(ρcφʹ * sH / cδ)) // (40.4) p. 280 Δδ = -π.Mul(ρsφʹ*cδ - ρcφʹ*cH*sδ) // (40.5) p. 280 return }
// Topocentric2 returns topocentric corrections including parallax. // // This function implements the "non-rigorous" method descripted in the text. // // Note that results are corrections, not corrected coordinates. func Topocentric2(α, δ, Δ, ρsφʹ, ρcφʹ, L, jde float64) (Δα, Δδ float64) { π := Horizontal(Δ) θ0 := base.Time(sidereal.Apparent(jde)).Rad() H := base.PMod(θ0-L-α, 2*math.Pi) sH, cH := math.Sincos(H) sδ, cδ := math.Sincos(δ) Δα = -π * ρcφʹ * sH / cδ // (40.4) p. 280 Δδ = -π * (ρsφʹ*cδ - ρcφʹ*cH*sδ) // (40.5) p. 280 return }
func ExampleMean_a() { // Example 12.a, p. 88. jd := 2446895.5 s := sidereal.Mean(jd) sa := sidereal.Apparent(jd) fmt.Printf("%.4d\n", sexa.NewFmtTime(s)) fmt.Printf("%.4d\n", sexa.NewFmtTime(sa)) // Output: // 13ʰ10ᵐ46ˢ.3668 // 13ʰ10ᵐ46ˢ.1351 }
// Topocentric returns topocentric positions including parallax. // // Arguments α, δ are geocentric right ascension and declination in radians. // Δ is distance to the observed object in AU. ρsφʹ, ρcφʹ are parallax // constants (see package globe.) L is geographic longitude of the observer, // jde is time of observation. // // Results are observed topocentric ra and dec in radians. func Topocentric(α, δ, Δ, ρsφʹ, ρcφʹ, L, jde float64) (αʹ, δʹ float64) { π := Horizontal(Δ) θ0 := base.Time(sidereal.Apparent(jde)).Rad() H := base.PMod(θ0-L-α, 2*math.Pi) sπ := math.Sin(π) sH, cH := math.Sincos(H) sδ, cδ := math.Sincos(δ) Δα := math.Atan2(-ρcφʹ*sπ*sH, cδ-ρcφʹ*sπ*cH) // (40.2) p. 279 αʹ = α + Δα δʹ = math.Atan2((sδ-ρsφʹ*sπ)*math.Cos(Δα), cδ-ρcφʹ*sπ*cH) // (40.3) p. 279 return }
// Topocentric returns topocentric positions including parallax. // // Arguments α, δ are geocentric right ascension and declination in radians. // Δ is distance to the observed object in AU. ρsφʹ, ρcφʹ are parallax // constants (see package globe.) L is geographic longitude of the observer, // jde is time of observation. // // Results are observed topocentric ra and dec in radians. func Topocentric(α unit.RA, δ unit.Angle, Δ, ρsφʹ, ρcφʹ float64, L unit.Angle, jde float64) (αʹ unit.RA, δʹ unit.Angle) { π := Horizontal(Δ) θ0 := sidereal.Apparent(jde) H := (θ0.Angle() - L - unit.Angle(α)).Mod1() sπ := π.Sin() sH, cH := H.Sincos() sδ, cδ := δ.Sincos() // (40.2) p. 279 Δα := unit.HourAngle(math.Atan2(-ρcφʹ*sπ*sH, cδ-ρcφʹ*sπ*cH)) αʹ = α.Add(Δα) // (40.3) p. 279 δʹ = unit.Angle(math.Atan2((sδ-ρsφʹ*sπ)*Δα.Cos(), cδ-ρcφʹ*sπ*cH)) return }
// Topocentric3 returns topocentric hour angle and declination including parallax. // // This function implements the "alternative" method described in the text. // The method should be similarly rigorous to that of Topocentric() and results // should be virtually consistent. func Topocentric3(α unit.RA, δ unit.Angle, Δ, ρsφʹ, ρcφʹ float64, L unit.Angle, jde float64) (Hʹ unit.HourAngle, δʹ unit.Angle) { π := Horizontal(Δ) θ0 := sidereal.Apparent(jde) H := (θ0.Angle() - L - unit.Angle(α)).Mod1() sπ := π.Sin() sH, cH := H.Sincos() sδ, cδ := δ.Sincos() A := cδ * sH B := cδ*cH - ρcφʹ*sπ C := sδ - ρsφʹ*sπ q := math.Sqrt(A*A + B*B + C*C) Hʹ = unit.HourAngle(math.Atan2(A, B)) δʹ = unit.Angle(math.Asin(C / q)) return }
// Topocentric3 returns topocentric hour angle and declination including parallax. // // This function implements the "alternative" method described in the text. // The method should be similarly rigorous to that of Topocentric() and results // should be virtually consistent. func Topocentric3(α, δ, Δ, ρsφʹ, ρcφʹ, L, jde float64) (Hʹ, δʹ float64) { π := Horizontal(Δ) θ0 := base.Time(sidereal.Apparent(jde)).Rad() H := base.PMod(θ0-L-α, 2*math.Pi) sπ := math.Sin(π) sH, cH := math.Sincos(H) sδ, cδ := math.Sincos(δ) A := cδ * sH B := cδ*cH - ρcφʹ*sπ C := sδ - ρsφʹ*sπ q := math.Sqrt(A*A + B*B + C*C) Hʹ = math.Atan2(A, B) δʹ = math.Asin(C / q) return }
func ExampleHorizontal_EqToHz() { // Example 13.b, p. 95. eq := &coord.Equatorial{ RA: unit.NewRA(23, 9, 16.641), Dec: unit.NewAngle('-', 6, 43, 11.61), } g := &globe.Coord{ Lat: unit.NewAngle(' ', 38, 55, 17), Lon: unit.NewAngle(' ', 77, 3, 56), } jd := julian.TimeToJD(time.Date(1987, 4, 10, 19, 21, 0, 0, time.UTC)) st := sidereal.Apparent(jd) hz := new(coord.Horizontal).EqToHz(eq, g, st) fmt.Printf("A = %+.3j\n", sexa.FmtAngle(hz.Az)) fmt.Printf("h = %+.3j\n", sexa.FmtAngle(hz.Alt)) // Output: // A = +68°.034 // h = +15°.125 }
func ExampleHorizontal_EqToHz() { // Example 13.b, p. 95. eq := &coord.Equatorial{ RA: sexa.NewRA(23, 9, 16.641).Rad(), Dec: sexa.NewAngle(true, 6, 43, 11.61).Rad(), } g := &globe.Coord{ Lat: sexa.NewAngle(false, 38, 55, 17).Rad(), Lon: sexa.NewAngle(false, 77, 3, 56).Rad(), } jd := julian.TimeToJD(time.Date(1987, 4, 10, 19, 21, 0, 0, time.UTC)) st := sidereal.Apparent(jd) hz := new(coord.Horizontal).EqToHz(eq, g, st) AStr := fmt.Sprintf("%+.3j", sexa.NewFmtAngle(hz.Az)) hStr := fmt.Sprintf("%+.3j", sexa.NewFmtAngle(hz.Alt)) fmt.Println("A =", AStr) fmt.Println("h =", hStr) // Output: // A = +68°.034 // h = +15°.125 }
func ExampleTopocentric3() { // same test case as example 40.a, p. 280 α := unit.RAFromDeg(339.530208) δ := unit.AngleFromDeg(-15.771083) Δ := .37276 ρsφʹ := .546861 ρcφʹ := .836339 L := unit.Angle(unit.NewHourAngle(' ', 7, 47, 27)) jde := julian.CalendarGregorianToJD(2003, 8, 28+ unit.NewTime(' ', 3, 17, 0).Day()) Hʹ, δʹ := parallax.Topocentric3(α, δ, Δ, ρsφʹ, ρcφʹ, L, jde) fmt.Printf("Hʹ = %.2d\n", sexa.FmtHourAngle(Hʹ)) θ0 := sidereal.Apparent(jde) αʹ := unit.RAFromRad(θ0.Rad() - L.Rad() - Hʹ.Rad()) // same result as example 40.a, p. 280 fmt.Printf("αʹ = %.2d\n", sexa.FmtRA(αʹ)) fmt.Printf("δʹ = %.1d\n", sexa.FmtAngle(δʹ)) // Output: // Hʹ = -4ʰ44ᵐ50ˢ.28 // αʹ = 22ʰ38ᵐ8ˢ.54 // δʹ = -15°46′30″.0 }
func TestTopocentric3(t *testing.T) { // same test case as example 40.a, p. 280 α := 339.530208 * math.Pi / 180 δ := -15.771083 * math.Pi / 180 Δ := .37276 ρsφʹ := .546861 ρcφʹ := .836339 L := base.NewHourAngle(false, 7, 47, 27).Rad() jde := julian.CalendarGregorianToJD(2003, 8, 28+(3+17./60)/24) // reference result αʹ, δʹ1 := parallax.Topocentric(α, δ, Δ, ρsφʹ, ρcφʹ, L, jde) // result to test Hʹ, δʹ3 := parallax.Topocentric3(α, δ, Δ, ρsφʹ, ρcφʹ, L, jde) // test θ0 := base.Time(sidereal.Apparent(jde)).Rad() if math.Abs(base.PMod(Hʹ-(θ0-L-αʹ)+1, 2*math.Pi)-1) > 1e-15 { t.Fatal(Hʹ, θ0-L-αʹ) } if math.Abs(δʹ3-δʹ1) > 1e-15 { t.Fatal(δʹ3, δʹ1) } }