func ExampleProperMotion3D() { // Example 21.d, p. 141. eqFrom := &coord.Equatorial{ RA: base.NewRA(6, 45, 8.871).Rad(), Dec: base.NewAngle(true, 16, 42, 57.99).Rad(), } mra := base.NewHourAngle(false, 0, 0, -0.03847) mdec := base.NewAngle(false, 0, 0, -1.2053) r := 2.64 // given in correct unit mr := -7.6 / 977792 // magic conversion factor eqTo := &coord.Equatorial{} fmt.Printf("Δr = %.9f, Δα = %.10f, Δδ = %.10f\n", mr, mra, mdec) for _, epoch := range []float64{1000, 0, -1000, -2000, -10000} { precess.ProperMotion3D(eqFrom, eqTo, 2000, epoch, r, mr, mra, mdec) fmt.Printf("%8.1f %0.2d %-0.1d\n", epoch, base.NewFmtRA(eqTo.RA), base.NewFmtAngle(eqTo.Dec)) } // Output: // Δr = -0.000007773, Δα = -0.0000027976, Δδ = -0.0000058435 // 1000.0 6ʰ45ᵐ47ˢ.16 -16°22′56″.0 // 0.0 6ʰ46ᵐ25ˢ.09 -16°03′00″.8 // -1000.0 6ʰ47ᵐ02ˢ.67 -15°43′12″.3 // -2000.0 6ʰ47ᵐ39ˢ.91 -15°23′30″.6 // -10000.0 6ʰ52ᵐ25ˢ.72 -12°50′06″.7 }
// Exercise, p. 136. func TestPosition(t *testing.T) { eqFrom := &coord.Equatorial{ base.NewRA(2, 31, 48.704).Rad(), base.NewAngle(false, 89, 15, 50.72).Rad(), } eqTo := &coord.Equatorial{} mα := base.NewHourAngle(false, 0, 0, 0.19877) mδ := base.NewAngle(true, 0, 0, 0.0152) for _, tc := range []struct { α, δ string jde float64 }{ {"1 22 33.90", "88 46 26.18", base.BesselianYearToJDE(1900)}, {"3 48 16.43", "89 27 15.38", base.JulianYearToJDE(2050)}, {"5 53 29.17", "89 32 22.18", base.JulianYearToJDE(2100)}, } { epochTo := base.JDEToJulianYear(tc.jde) precess.Position(eqFrom, eqTo, 2000.0, epochTo, mα, mδ) αStr := fmt.Sprintf("%.2x", base.NewFmtRA(eqTo.RA)) δStr := fmt.Sprintf("%.2x", base.NewFmtAngle(eqTo.Dec)) if αStr != tc.α { t.Fatal("got:", αStr, "want:", tc.α) } if δStr != tc.δ { t.Fatal(δStr) } } }
func TestPrecessor_Precess(t *testing.T) { // Exercise, p. 136. eqFrom := &coord.Equatorial{ RA: base.NewRA(2, 31, 48.704).Rad(), Dec: base.NewAngle(false, 89, 15, 50.72).Rad(), } mα := base.NewHourAngle(false, 0, 0, .19877) mδ := base.NewAngle(false, 0, 0, -.0152) epochs := []float64{ base.JDEToJulianYear(base.B1900), 2050, 2100, } answer := []string{ "α = 1ʰ22ᵐ33ˢ.90 δ = +88°46′26″.18", "α = 3ʰ48ᵐ16ˢ.43 δ = +89°27′15″.38", "α = 5ʰ53ᵐ29ˢ.17 δ = +89°32′22″.18", } eqTo := &coord.Equatorial{} for i, epochTo := range epochs { precess.Position(eqFrom, eqTo, 2000, epochTo, mα, mδ) if answer[i] != fmt.Sprintf("α = %0.2d δ = %+0.2d", base.NewFmtRA(eqTo.RA), base.NewFmtAngle(eqTo.Dec)) { t.Fatal(i) } } }
// ApproxAnnualPrecession returns approximate annual precision in right // ascension and declination. // // The two epochs should be within a few hundred years. // The declinations should not be too close to the poles. func ApproxAnnualPrecession(eq *coord.Equatorial, epochFrom, epochTo float64) (Δα base.HourAngle, Δδ base.Angle) { m, na, nd := mn(epochFrom, epochTo) sa, ca := math.Sincos(eq.RA) // (21.1) p. 132 Δαs := m + na*sa*math.Tan(eq.Dec) // seconds of RA Δδs := nd * ca // seconds of Dec return base.NewHourAngle(false, 0, 0, Δαs), base.NewAngle(false, 0, 0, Δδs) }
func ExampleTopocentric2() { // Example 40.a, p. 280 Δα, Δδ := parallax.Topocentric2(339.530208*math.Pi/180, -15.771083*math.Pi/180, .37276, .546861, .836339, base.NewHourAngle(false, 7, 47, 27).Rad(), julian.CalendarGregorianToJD(2003, 8, 28+(3+17./60)/24)) fmt.Printf("Δα = %.2f sec of RA\n", Δα*180/math.Pi*60*60/15) fmt.Printf("Δδ = %.1f sec\n", Δδ*180/math.Pi*60*60) // Output: // Δα = 1.29 sec of RA // Δδ = -14.1 sec }
func ExampleTopocentric() { // Example 40.a, p. 280 α, δ := parallax.Topocentric(339.530208*math.Pi/180, -15.771083*math.Pi/180, .37276, .546861, .836339, base.NewHourAngle(false, 7, 47, 27).Rad(), julian.CalendarGregorianToJD(2003, 8, 28+(3+17./60)/24)) fmt.Printf("α' = %.2d\n", base.NewFmtRA(α)) fmt.Printf("δ' = %.1d\n", base.NewFmtAngle(δ)) // Output: // α' = 22ʰ38ᵐ8ˢ.54 // δ' = -15°46′30″.0 }
func ExamplePositionRonVondrak() { // Example 23.b, p. 156 jd := julian.CalendarGregorianToJD(2028, 11, 13.19) eq := &coord.Equatorial{ RA: base.NewRA(2, 44, 11.986).Rad(), Dec: base.NewAngle(false, 49, 13, 42.48).Rad(), } apparent.PositionRonVondrak(eq, eq, base.JDEToJulianYear(jd), base.NewHourAngle(false, 0, 0, 0.03425), base.NewAngle(true, 0, 0, 0.0895)) fmt.Printf("α = %0.3d\n", base.NewFmtRA(eq.RA)) fmt.Printf("δ = %0.2d\n", base.NewFmtAngle(eq.Dec)) // Output: // α = 2ʰ46ᵐ14ˢ.392 // δ = 49°21′07″.45 }
func ExampleApproxPosition() { // Example 21.a, p. 132. eq := &coord.Equatorial{ base.NewRA(10, 8, 22.3).Rad(), base.NewAngle(false, 11, 58, 2).Rad(), } epochFrom := 2000.0 epochTo := 1978.0 mα := base.NewHourAngle(true, 0, 0, 0.0169) mδ := base.NewAngle(false, 0, 0, 0.006) precess.ApproxPosition(eq, eq, epochFrom, epochTo, mα, mδ) fmt.Printf("%0.1d\n", base.NewFmtRA(eq.RA)) fmt.Printf("%+0d\n", base.NewFmtAngle(eq.Dec)) // Output: // 10ʰ07ᵐ12ˢ.1 // +12°04′32″ }
func ExamplePosition() { // Example 21.b, p. 135. eq := &coord.Equatorial{ base.NewRA(2, 44, 11.986).Rad(), base.NewAngle(false, 49, 13, 42.48).Rad(), } epochFrom := 2000.0 jdTo := julian.CalendarGregorianToJD(2028, 11, 13.19) epochTo := base.JDEToJulianYear(jdTo) precess.Position(eq, eq, epochFrom, epochTo, base.NewHourAngle(false, 0, 0, 0.03425), base.NewAngle(true, 0, 0, 0.0895)) fmt.Printf("%0.3d\n", base.NewFmtRA(eq.RA)) fmt.Printf("%+0.2d\n", base.NewFmtAngle(eq.Dec)) // Output: // 2ʰ46ᵐ11ˢ.331 // +49°20′54″.54 }
// Test with proper motion of Regulus, with equatorial motions given // in Example 21.a, p. 132, and ecliptic motions given in table 21.A, // p. 138. func TestEqProperMotionToEcl(t *testing.T) { ε := coord.NewObliquity(nutation.MeanObliquity(base.J2000)) mλ, mβ := eqProperMotionToEcl( // eq motions from p. 132. base.NewHourAngle(true, 0, 0, 0.0169).Rad(), base.NewAngle(false, 0, 0, 0.006).Rad(), 2000.0, // eq coordinates from p. 132. new(coord.Ecliptic).EqToEcl(&coord.Equatorial{ RA: base.NewRA(10, 8, 22.3).Rad(), Dec: base.NewAngle(false, 11, 58, 2).Rad(), }, ε)) d := math.Abs((mλ - base.NewAngle(true, 0, 0, .2348).Rad()) / mλ) if d*169 > 1 { // 169 = significant digits of given lon t.Fatal("mλ") } d = math.Abs((mβ - base.NewAngle(true, 0, 0, 0.0813).Rad()) / mβ) if d*6 > 1 { // 6 = significant digit of given lat t.Fatal("mβ") } }
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) } }