Beispiel #1
0
// EqToHz computes Horizontal coordinates from equatorial coordinates.
//
//	α: right ascension coordinate to transform, in radians
//	δ: declination coordinate to transform, in radians
//	φ: latitude of observer on Earth
//	ψ: longitude of observer on Earth
//	st: sidereal time at Greenwich at time of observation.
//
// Sidereal time must be consistent with the equatorial coordinates.
// If coordinates are apparent, sidereal time must be apparent as well.
//
// Results:
//
//	A: azimuth of observed point in radians, measured westward from the South.
//	h: elevation, or height of observed point in radians above horizon.
func EqToHz(α, δ, φ, ψ, st float64) (A, h float64) {
	H := base.Time(st).Rad() - ψ - α
	sH, cH := math.Sincos(H)
	sφ, cφ := math.Sincos(φ)
	sδ, cδ := math.Sincos(ψ)
	A = math.Atan2(sH, cH*sφ-(sδ/cδ)*cφ) // (13.5) p. 93
	h = math.Asin(sφ*sδ + cφ*cδ*cH)      // (13.6) p. 93
	return
}
Beispiel #2
0
// EqToHz computes Horizontal coordinates from equatorial coordinates.
//
// Argument g is the location of the observer on the Earth.  Argument st
// is the sidereal time at Greenwich.
//
// Sidereal time must be consistent with the equatorial coordinates.
// If coordinates are apparent, sidereal time must be apparent as well.
func (hz *Horizontal) EqToHz(eq *Equatorial, g *globe.Coord, st float64) *Horizontal {
	H := base.Time(st).Rad() - g.Lon - eq.RA
	sH, cH := math.Sincos(H)
	sφ, cφ := math.Sincos(g.Lat)
	sδ, cδ := math.Sincos(eq.Dec)
	hz.Az = math.Atan2(sH, cH*sφ-(sδ/cδ)*cφ) // (13.5) p. 93
	hz.Alt = math.Asin(sφ*sδ + cφ*cδ*cH)     // (13.6) p. 93
	return hz
}
Beispiel #3
0
// HzToEq transforms horizontal coordinates to equatorial coordinates.
//
//	A: azimuth
//	h: elevation
//	φ: latitude of observer on Earth
//	ψ: longitude of observer on Earth
//	st: sidereal time at Greenwich at time of observation.
//
// Sidereal time must be consistent with the equatorial coordinates.
// If coordinates are apparent, sidereal time must be apparent as well.
//
// Results:
//
//	α: right ascension
//	δ: declination
func HzToEq(A, h, φ, ψ, st float64) (α, δ float64) {
	sA, cA := math.Sincos(A)
	sh, ch := math.Sincos(h)
	sφ, cφ := math.Sincos(φ)
	H := math.Atan2(sA, cA*sφ+sh/ch*cφ)
	α = base.PMod(base.Time(st).Rad()-ψ-H, 2*math.Pi)
	δ = math.Asin(sφ*sh - cφ*ch*cA)
	return
}
Beispiel #4
0
// HzToEq transforms horizontal coordinates to equatorial coordinates.
//
// Sidereal time must be consistent with the equatorial coordinates.
// If coordinates are apparent, sidereal time must be apparent as well.
func (eq *Equatorial) HzToEq(hz *Horizontal, g globe.Coord, st float64) *Equatorial {
	sA, cA := math.Sincos(hz.Az)
	sh, ch := math.Sincos(hz.Alt)
	sφ, cφ := math.Sincos(g.Lat)
	H := math.Atan2(sA, cA*sφ+sh/ch*cφ)
	eq.RA = base.PMod(base.Time(st).Rad()-g.Lon-H, 2*math.Pi)
	eq.Dec = math.Asin(sφ*sh - cφ*ch*cA)
	return eq
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
// 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
}
Beispiel #8
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)
	}
}