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) } } }
// 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) } } }
// Exercise, p. 136. func TestPosition(t *testing.T) { eqFrom := &coord.Equatorial{ unit.NewRA(2, 31, 48.704), unit.NewAngle(' ', 89, 15, 50.72), } eqTo := &coord.Equatorial{} mα := unit.HourAngleFromSec(0.19877) mδ := unit.AngleFromSec(-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("%.2s", sexa.FmtRA(eqTo.RA)) δStr := fmt.Sprintf("%.2s", sexa.FmtAngle(eqTo.Dec)) if αStr != tc.α { t.Fatal("got:", αStr, "want:", tc.α) } if δStr != tc.δ { t.Fatal(δStr) } } }
// Position computes the apparent position of an object. // // Position is computed for equatorial coordinates in eqFrom, considering // proper motion, precession, nutation, and aberration. Result is in // eqTo. EqFrom and eqTo must be non-nil, but may point to the same struct. func Position(eqFrom, eqTo *coord.Equatorial, epochFrom, epochTo float64, mα sexa.HourAngle, mδ sexa.Angle) *coord.Equatorial { precess.Position(eqFrom, eqTo, epochFrom, epochTo, mα, mδ) jd := base.JulianYearToJDE(epochTo) Δα1, Δδ1 := Nutation(eqTo.RA, eqTo.Dec, jd) Δα2, Δδ2 := Aberration(eqTo.RA, eqTo.Dec, jd) eqTo.RA += Δα1 + Δα2 eqTo.Dec += Δδ1 + Δδ2 return eqTo }
// PositionRonVondrak computes the apparent position of an object using // the Ron-Vondrák expression for aberration. // // Position is computed for equatorial coordinates in eqFrom, considering // proper motion, aberration, precession, and nutation. Result is in // eqTo. EqFrom and eqTo must be non-nil, but may point to the same struct. // // Note the Ron-Vondrák expression is only valid for the epoch J2000. // EqFrom must be coordinates at epoch J2000. func PositionRonVondrak(eqFrom, eqTo *coord.Equatorial, epochTo float64, mα sexa.HourAngle, mδ sexa.Angle) *coord.Equatorial { t := epochTo - 2000 eqTo.RA = eqFrom.RA + mα.Rad()*t eqTo.Dec = eqFrom.Dec + mδ.Rad()*t jd := base.JulianYearToJDE(epochTo) Δα, Δδ := AberrationRonVondrak(eqTo.RA, eqTo.Dec, jd) eqTo.RA += Δα eqTo.Dec += Δδ precess.Position(eqTo, eqTo, 2000, epochTo, 0, 0) Δα1, Δδ1 := Nutation(eqTo.RA, eqTo.Dec, jd) eqTo.RA += Δα1 eqTo.Dec += Δδ1 return eqTo }
// PositionRonVondrak computes the apparent position of an object using // the Ron-Vondrák expression for aberration. // // Position is computed for equatorial coordinates in eqFrom, considering // proper motion, aberration, precession, and nutation. Result is in // eqTo. EqFrom and eqTo must be non-nil, but may point to the same struct. // // Note the Ron-Vondrák expression is only valid for the epoch J2000. // EqFrom must be coordinates at epoch J2000. func PositionRonVondrak(eqFrom, eqTo *coord.Equatorial, epochTo float64, mα unit.HourAngle, mδ unit.Angle) *coord.Equatorial { t := epochTo - 2000 eqTo.RA = eqFrom.RA.Add(mα.Mul(t)) eqTo.Dec = eqFrom.Dec + mδ.Mul(t) jd := base.JulianYearToJDE(epochTo) Δα, Δδ := AberrationRonVondrak(eqTo.RA, eqTo.Dec, jd) eqTo.RA = eqTo.RA.Add(Δα) eqTo.Dec += Δδ precess.Position(eqTo, eqTo, 2000, epochTo, 0, 0) Δα1, Δδ1 := Nutation(eqTo.RA, eqTo.Dec, jd) eqTo.RA = eqTo.RA.Add(Δα1) eqTo.Dec += Δδ1 return eqTo }
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 }