예제 #1
0
파일: coord.go 프로젝트: soniakeys/meeus
// EqToEcl converts equatorial coordinates to ecliptic coordinates.
func (ecl *Ecliptic) EqToEcl(eq *Equatorial, ε *Obliquity) *Ecliptic {
	sα, cα := eq.RA.Sincos()
	sδ, cδ := eq.Dec.Sincos()
	ecl.Lon = unit.Angle(math.Atan2(sα*ε.C+(sδ/cδ)*ε.S, cα)) // (13.1) p. 93
	ecl.Lat = unit.Angle(math.Asin(sδ*ε.C - cδ*ε.S*sα))      // (13.2) p. 93
	return ecl
}
예제 #2
0
파일: coord.go 프로젝트: soniakeys/meeus
// EqToEcl converts equatorial coordinates to ecliptic coordinates.
//
//	α: right ascension coordinate to transform
//	δ: declination coordinate to transform
//	sε: sine of obliquity of the ecliptic
//	cε: cosine of obliquity of the ecliptic
//
// Results:
//
//	λ: ecliptic longitude
//	β: ecliptic latitude
func EqToEcl(α unit.RA, δ unit.Angle, sε, cε float64) (λ, β unit.Angle) {
	sα, cα := α.Sincos()
	sδ, cδ := δ.Sincos()
	λ = unit.Angle(math.Atan2(sα*cε+(sδ/cδ)*sε, cα)) // (13.1) p. 93
	β = unit.Angle(math.Asin(sδ*cε - cδ*sε*sα))      // (13.2) p. 93
	return
}
예제 #3
0
파일: elliptic.go 프로젝트: soniakeys/meeus
// Position returns observed equatorial coordinates of a planet at a given time.
//
// Argument p must be a valid V87Planet object for the observed planet.
// Argument earth must be a valid V87Planet object for Earth.
//
// Results are right ascension and declination, α and δ in radians.
func Position(p, earth *pp.V87Planet, jde float64) (α unit.RA, δ unit.Angle) {
	L0, B0, R0 := earth.Position(jde)
	L, B, R := p.Position(jde)
	sB0, cB0 := B0.Sincos()
	sL0, cL0 := L0.Sincos()
	sB, cB := B.Sincos()
	sL, cL := L.Sincos()
	x := R*cB*cL - R0*cB0*cL0
	y := R*cB*sL - R0*cB0*sL0
	z := R*sB - R0*sB0
	{
		Δ := math.Sqrt(x*x + y*y + z*z) // (33.4) p. 224
		τ := base.LightTime(Δ)
		// repeating with jde-τ
		L, B, R = p.Position(jde - τ)
		sB, cB = B.Sincos()
		sL, cL = L.Sincos()
		x = R*cB*cL - R0*cB0*cL0
		y = R*cB*sL - R0*cB0*sL0
		z = R*sB - R0*sB0
	}
	λ := unit.Angle(math.Atan2(y, x))                // (33.1) p. 223
	β := unit.Angle(math.Atan2(z, math.Hypot(x, y))) // (33.2) p. 223
	Δλ, Δβ := apparent.EclipticAberration(λ, β, jde)
	λ, β = pp.ToFK5(λ+Δλ, β+Δβ, jde)
	Δψ, Δε := nutation.Nutation(jde)
	λ += Δψ
	sε, cε := (nutation.MeanObliquity(jde) + Δε).Sincos()
	return coord.EclToEq(λ, β, sε, cε)
	// Meeus gives a formula for elongation but doesn't spell out how to
	// obtain term λ0 and doesn't give an example solution.
}
예제 #4
0
파일: line.go 프로젝트: soniakeys/meeus
// AngleError returns both an angle as in the function Angle, and an error
// as in the function Error.
//
// The algorithm is by B. Pessens.
func AngleError(r1, d1, r2, d2, r3, d3 unit.Angle) (ψ, ω unit.Angle) {
	sr1, cr1 := r1.Sincos()
	sd1, cd1 := d1.Sincos()
	sr2, cr2 := r2.Sincos()
	sd2, cd2 := d2.Sincos()
	sr3, cr3 := r3.Sincos()
	sd3, cd3 := d3.Sincos()
	a1 := cd1 * cr1
	a2 := cd2 * cr2
	a3 := cd3 * cr3
	b1 := cd1 * sr1
	b2 := cd2 * sr2
	b3 := cd3 * sr3
	c1 := sd1
	c2 := sd2
	c3 := sd3
	l1 := b1*c2 - b2*c1
	l2 := b2*c3 - b3*c2
	l3 := b1*c3 - b3*c1
	m1 := c1*a2 - c2*a1
	m2 := c2*a3 - c3*a2
	m3 := c1*a3 - c3*a1
	n1 := a1*b2 - a2*b1
	n2 := a2*b3 - a3*b2
	n3 := a1*b3 - a3*b1
	ψ = unit.Angle(math.Acos((l1*l2 + m1*m2 + n1*n2) /
		(math.Sqrt(l1*l1+m1*m1+n1*n1) * math.Sqrt(l2*l2+m2*m2+n2*n2))))
	ω = unit.Angle(math.Asin((a2*l3 + b2*m3 + c2*n3) /
		(math.Sqrt(a2*a2+b2*b2+c2*c2) * math.Sqrt(l3*l3+m3*m3+n3*n3))))
	return
}
예제 #5
0
파일: precess.go 프로젝트: soniakeys/meeus
// NewEclipticPrecessor constructs an EclipticPrecessor object and initializes
// it to precess coordinates from epochFrom to epochTo.
func NewEclipticPrecessor(epochFrom, epochTo float64) *EclipticPrecessor {
	// (21.5) p. 136
	ηCoeff := ηt
	πCoeff := πt
	pCoeff := pt
	if epochFrom != 2000 {
		T := (epochFrom - 2000) * .01
		ηCoeff = []float64{
			base.Horner(T, ηT...),
			-0.03302*s + 0.000598*s*T,
			0.000060 * s}
		πCoeff = []float64{
			base.Horner(T, πT...),
			-869.8089*s - 0.50491*s*T,
			0.03536 * s}
		pCoeff = []float64{
			base.Horner(T, pT...),
			1.11113*s - 0.000042*s*T,
			-0.000006 * s}
	}
	t := (epochTo - epochFrom) * .01
	p := &EclipticPrecessor{
		π: unit.Angle(base.Horner(t, πCoeff...)),
		p: unit.Angle(base.Horner(t, pCoeff...) * t),
	}
	η := unit.Angle(base.Horner(t, ηCoeff...) * t)
	p.sη, p.cη = η.Sincos()
	return p
}
예제 #6
0
파일: coord.go 프로젝트: soniakeys/meeus
// EqToHz computes Horizontal coordinates from equatorial coordinates.
//
//	α: right ascension coordinate to transform
//	δ: declination coordinate to transform
//	φ: 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, measured westward from the South.
//	h: elevation, or height of observed point above horizon.
func EqToHz(α unit.RA, δ, φ, ψ unit.Angle, st unit.Time) (A, h unit.Angle) {
	H := st.Rad() - ψ.Rad() - α.Rad()
	sH, cH := math.Sincos(H)
	sφ, cφ := φ.Sincos()
	sδ, cδ := ψ.Sincos()
	A = unit.Angle(math.Atan2(sH, cH*sφ-(sδ/cδ)*cφ)) // (13.5) p. 93
	h = unit.Angle(math.Asin(sφ*sδ + cφ*cδ*cH))      // (13.6) p. 93
	return
}
예제 #7
0
파일: coord.go 프로젝트: soniakeys/meeus
// 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 unit.Time) *Horizontal {
	H := st.Rad() - g.Lon.Rad() - eq.RA.Rad()
	sH, cH := math.Sincos(H)
	sφ, cφ := g.Lat.Sincos()
	sδ, cδ := eq.Dec.Sincos()
	hz.Az = unit.Angle(math.Atan2(sH, cH*sφ-(sδ/cδ)*cφ)) // (13.5) p. 93
	hz.Alt = unit.Angle(math.Asin(sφ*sδ + cφ*cδ*cH))     // (13.6) p. 93
	return hz
}
예제 #8
0
파일: angle.go 프로젝트: soniakeys/meeus
// Sep returns the angular separation between two celestial bodies.
//
// The algorithm is numerically naïve, and while patched up a bit for
// small separations, remains unstable for separations near π.
func Sep(r1, d1, r2, d2 unit.Angle) unit.Angle {
	sd1, cd1 := d1.Sincos()
	sd2, cd2 := d2.Sincos()
	cd := sd1*sd2 + cd1*cd2*(r1-r2).Cos() // (17.1) p. 109
	if cd < base.CosSmallAngle {
		return unit.Angle(math.Acos(cd))
	}
	// (17.2) p. 109
	return unit.Angle(math.Hypot((r2-r1).Rad()*cd1, (d2 - d1).Rad()))
}
예제 #9
0
파일: moon.go 프로젝트: soniakeys/meeus
func (m *moon) optical(λ, β unit.Angle) (lʹ, bʹ, A unit.Angle) {
	// (53.1) p. 372
	W := λ - m.Ω // (λ without nutation)
	sW, cW := W.Sincos()
	sβ, cβ := β.Sincos()
	A = unit.Angle(math.Atan2(sW*cβ*cI-sβ*sI, cW*cβ))
	lʹ = (A - m.F).Mod1()
	bʹ = unit.Angle(math.Asin(-sW*cβ*sI - sβ*cI))
	return
}
예제 #10
0
파일: binary.go 프로젝트: soniakeys/meeus
// Position computes apparent position angle and angular distance of
// components of a binary star.
//
//	e is eccentricity of the true orbit
//	a is angular apparent semimajor axis
//	i is inclination relative to the line of sight
//	Ω is position angle of the ascending node
//	ω is longitude of periastron
//	E is eccentric anomaly, computed for example with package kepler
//	   and the mean anomaly as returned by function M in this package.
//
// Return value θ is the apparent position angle, ρ is the angular distance.
func Position(e float64, a, i, Ω, ω, E unit.Angle) (θ, ρ unit.Angle) {
	r := a.Mul(1 - e*E.Cos())
	ν := unit.Angle(2 * math.Atan(math.Sqrt((1+e)/(1-e))*E.Div(2).Tan()))
	sνω, cνω := (ν + ω).Sincos()
	ci := i.Cos()
	num := sνω * ci
	θ = (unit.Angle(math.Atan2(num, cνω)) + Ω).Mod1()
	ρ = r.Mul(math.Sqrt(num*num + cνω*cνω))
	return
}
예제 #11
0
파일: precess.go 프로젝트: soniakeys/meeus
func eqProperMotionToEcl(mα unit.HourAngle, mδ unit.Angle, epoch float64, pos *coord.Ecliptic) (mλ, mβ unit.Angle) {
	ε := nutation.MeanObliquity(base.JulianYearToJDE(epoch))
	sε, cε := ε.Sincos()
	α, δ := coord.EclToEq(pos.Lon, pos.Lat, sε, cε)
	sα, cα := α.Sincos()
	sδ, cδ := δ.Sincos()
	cβ := pos.Lat.Cos()
	mλ = (mδ.Mul(sε*cα) + unit.Angle(mα).Mul(cδ*(cε*cδ+sε*sδ*sα))).Div(cβ * cβ)
	mβ = (mδ.Mul(cε*cδ+sε*sδ*sα) - unit.Angle(mα).Mul(sε*cα*cδ)).Div(cβ)
	return
}
예제 #12
0
파일: coord.go 프로젝트: soniakeys/meeus
// EqToGal converts equatorial coordinates to galactic coordinates.
//
// Equatorial coordinates must be referred to the standard equinox of B1950.0.
// For conversion to B1950, see package precess and utility functions in
// package "unit".
func (g *Galactic) EqToGal(eq *Equatorial) *Galactic {
	sdα, cdα := (galacticNorth.RA - eq.RA).Sincos()
	sgδ, cgδ := galacticNorth.Dec.Sincos()
	sδ, cδ := eq.Dec.Sincos()
	// (13.7) p. 94
	x := unit.Angle(math.Atan2(sdα, cdα*sgδ-(sδ/cδ)*cgδ))
	g.Lon = (galacticLon0 + math.Pi - x).Mod1()
	// (13.8) p. 94
	g.Lat = unit.Angle(math.Asin(sδ*sgδ + cδ*cgδ*cdα))
	return g
}
예제 #13
0
파일: coord.go 프로젝트: soniakeys/meeus
// EqToGal converts equatorial coordinates to galactic coordinates.
//
// Equatorial coordinates must be referred to the standard equinox of B1950.0.
// For conversion to B1950, see package precess and utility functions in
// package "common".
func EqToGal(α unit.RA, δ unit.Angle) (l, b unit.Angle) {
	sdα, cdα := (galacticNorth.RA - α).Sincos()
	sgδ, cgδ := galacticNorth.Dec.Sincos()
	sδ, cδ := δ.Sincos()
	// (13.7) p. 94
	x := unit.Angle(math.Atan2(sdα, cdα*sgδ-(sδ/cδ)*cgδ))
	l = (galacticLon0 + math.Pi - x).Mod1()
	// (13.8) p. 94
	b = unit.Angle(math.Asin(sδ*sgδ + cδ*cgδ*cdα))
	return
}
예제 #14
0
// EclipticAtHorizon computes how the plane of the ecliptic intersects
// the horizon at a given local sidereal time as observed from a given
// geographic latitude.
//
//	ε is obliquity of the ecliptic.
//	φ is geographic latitude of observer.
//	θ is local sidereal time.
//
//	λ1 and λ2 are ecliptic longitudes where the ecliptic intersects the horizon.
//	I is the angle at which the ecliptic intersects the horizon.
func EclipticAtHorizon(ε, φ unit.Angle, θ unit.Time) (λ1, λ2, I unit.Angle) {
	sε, cε := ε.Sincos()
	sφ, cφ := φ.Sincos()
	sθ, cθ := θ.Angle().Sincos()
	// (14.2) p. 99
	λ := unit.Angle(math.Atan2(-cθ, sε*(sφ/cφ)+cε*sθ))
	if λ < 0 {
		λ += math.Pi
	}
	// (14.3) p. 99
	return λ, λ + math.Pi, unit.Angle(math.Acos(cε*sφ - sε*cφ*sθ))
}
예제 #15
0
// ReduceB1950ToJ2000 reduces orbital elements of a solar system body from
// equinox B1950 in the FK4 system to equinox J2000 in the FK5 system.
func ReduceB1950FK4ToJ2000FK5(eFrom, eTo *Elements) *Elements {
	W := _L + eFrom.Node
	si, ci := eFrom.Inc.Sincos()
	sJ, cJ := _J.Sincos()
	sW, cW := W.Sincos()
	eTo.Inc = unit.Angle(math.Acos(ci*cJ - si*sJ*cW))
	eTo.Node = (unit.Angle(math.Atan2(si*sW, ci*sJ+si*cJ*cW)) -
		_Lp).Mod1()
	eTo.Peri = (eFrom.Peri +
		unit.Angle(math.Atan2(sJ*sW, si*cJ+ci*sJ*cW))).Mod1()
	return eTo
}
예제 #16
0
파일: precess.go 프로젝트: soniakeys/meeus
// ReduceElements reduces orbital elements of a solar system body from one
// equinox to another.
//
// This function is described in chapter 24, but is located in this
// package so it can be a method of EclipticPrecessor.
func (p *EclipticPrecessor) ReduceElements(eFrom, eTo *elementequinox.Elements) *elementequinox.Elements {
	ψ := p.π + p.p
	si, ci := eFrom.Inc.Sincos()
	snp, cnp := (eFrom.Node - p.π).Sincos()
	// (24.1) p. 159
	eTo.Inc = unit.Angle(math.Acos(ci*p.cη + si*p.sη*cnp))
	// (24.2) p. 159
	eTo.Node = ψ +
		unit.Angle(math.Atan2(si*snp, p.cη*si*cnp-p.sη*ci))
	// (24.3) p. 160
	eTo.Peri = eFrom.Peri +
		unit.Angle(math.Atan2(-p.sη*snp, si*p.cη-ci*p.sη*cnp))
	return eTo
}
예제 #17
0
파일: parallax.go 프로젝트: soniakeys/meeus
// 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
}
예제 #18
0
파일: precess.go 프로젝트: soniakeys/meeus
// EclipticPrecess precesses coordinates eclFrom, leaving result in eclTo.
//
// The same struct may be used for eclFrom and eclTo.
// EclTo is returned for convenience.
func (p *EclipticPrecessor) Precess(eclFrom, eclTo *coord.Ecliptic) *coord.Ecliptic {
	// (21.7) p. 137
	sβ, cβ := eclFrom.Lat.Sincos()
	sd, cd := (p.π - eclFrom.Lon).Sincos()
	A := p.cη*cβ*sd - p.sη*sβ
	B := cβ * cd
	C := p.cη*sβ + p.sη*cβ*sd
	eclTo.Lon = p.p + p.π - unit.Angle(math.Atan2(A, B))
	if C < base.CosSmallAngle {
		eclTo.Lat = unit.Angle(math.Asin(C))
	} else {
		eclTo.Lat = unit.Angle(math.Acos(math.Hypot(A, B))) // near pole
	}
	return eclTo
}
예제 #19
0
파일: parallax.go 프로젝트: soniakeys/meeus
// 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
}
예제 #20
0
파일: precess.go 프로젝트: soniakeys/meeus
// Precess precesses coordinates eqFrom, leaving result in eqTo.
//
// The same struct may be used for eqFrom and eqTo.
// EqTo is returned for convenience.
func (p *Precessor) Precess(eqFrom, eqTo *coord.Equatorial) *coord.Equatorial {
	// (21.4) p. 134
	sδ, cδ := eqFrom.Dec.Sincos()
	sαζ, cαζ := (eqFrom.RA + p.ζ).Sincos()
	A := cδ * sαζ
	B := p.cθ*cδ*cαζ - p.sθ*sδ
	C := p.sθ*cδ*cαζ + p.cθ*sδ
	eqTo.RA = unit.RAFromRad(math.Atan2(A, B) + p.z.Rad())
	if C < base.CosSmallAngle {
		eqTo.Dec = unit.Angle(math.Asin(C))
	} else {
		eqTo.Dec = unit.Angle(math.Acos(math.Hypot(A, B))) // near pole
	}
	return eqTo
}
예제 #21
0
파일: coord.go 프로젝트: soniakeys/meeus
// EclToEq converts ecliptic coordinates to equatorial coordinates.
//
//	λ: ecliptic longitude coordinate to transform
//	β: ecliptic latitude coordinate to transform
//	sε: sine of obliquity of the ecliptic
//	cε: cosine of obliquity of the ecliptic
//
// Results:
//	α: right ascension
//	δ: declination
func EclToEq(λ, β unit.Angle, sε, cε float64) (α unit.RA, δ unit.Angle) {
	sλ, cλ := λ.Sincos()
	sβ, cβ := β.Sincos()
	α = unit.RAFromRad(math.Atan2(sλ*cε-(sβ/cβ)*sε, cλ)) // (13.3) p. 93
	δ = unit.Angle(math.Asin(sβ*cε + cβ*sε*sλ))          // (13.4) p. 93
	return
}
예제 #22
0
// AnomalyDistance returns true anomaly and distance for near-parabolic orbits.
//
// Distance r returned in AU.
// An error is returned if the algorithm fails to converge.
func (e *Elements) AnomalyDistance(jde float64) (ν unit.Angle, r float64, err error) {
	// fairly literal translation of code on p. 246
	q1 := base.K * math.Sqrt((1+e.Ecc)/e.PDis) / (2 * e.PDis) // line 20
	g := (1 - e.Ecc) / (1 + e.Ecc)                            // line 20

	t := jde - e.TimeP // line 22
	if t == 0 {        // line 24
		return 0, e.PDis, nil
	}
	d1, d := 10000., 1e-9        // line 14
	q2 := q1 * t                 // line 28
	s := 2. / (3 * math.Abs(q2)) // line 30
	s = 2 / math.Tan(2*math.Atan(math.Cbrt(math.Tan(math.Atan(s)/2))))
	if t < 0 { // line 34
		s = -s
	}
	if e.Ecc != 1 { // line 36
		l := 0 // line 38
		for {
			s0 := s // line 40
			z := 1.
			y := s * s
			g1 := -y * s
			q3 := q2 + 2*g*s*y/3 // line 42
			for {
				z += 1                          // line 44
				g1 = -g1 * g * y                // line 46
				z1 := (z - (z+1)*g) / (2*z + 1) // line 48
				f := z1 * g1                    // line 50
				q3 += f                         // line 52
				if z > 50 || math.Abs(f) > d1 { // line 54
					return 0, 0, errors.New("No convergence")
				}
				if math.Abs(f) <= d { // line 56
					break
				}
			}
			l++ // line 58
			if l > 50 {
				return 0, 0, errors.New("No convergence")
			}
			for {
				s1 := s // line 60
				s = (2*s*s*s/3 + q3) / (s*s + 1)
				if math.Abs(s-s1) <= d { // line 62
					break
				}
			}
			if math.Abs(s-s0) <= d { // line 64
				break
			}
		}
	}
	ν = unit.Angle(2 * math.Atan(s))               // line 66
	r = e.PDis * (1 + e.Ecc) / (1 + e.Ecc*ν.Cos()) // line 68
	if ν < 0 {                                     // line 70
		ν += 2 * math.Pi
	}
	return
}
예제 #23
0
// ReduceB1950ToJ2000 reduces orbital elements of a solar system body from
// equinox B1950 to J2000.
func ReduceB1950ToJ2000(eFrom, eTo *Elements) *Elements {
	// (24.4) p. 161
	const S = .0001139788
	const C = .9999999935
	W := eFrom.Node - unit.AngleFromDeg(174.298782)
	si, ci := eFrom.Inc.Sincos()
	sW, cW := W.Sincos()
	A := si * sW
	B := C*si*cW - S*ci
	eTo.Inc = unit.Angle(math.Asin(math.Hypot(A, B)))
	eTo.Node = (unit.AngleFromDeg(174.997194) +
		unit.Angle(math.Atan2(A, B))).Mod1()
	eTo.Peri = (eFrom.Peri +
		unit.Angle(math.Atan2(-S*sW, C*si-S*ci*cW))).Mod1()
	return eTo
}
예제 #24
0
파일: moon.go 프로젝트: soniakeys/meeus
func (m *moon) sun(λ, β unit.Angle, Δ float64, earth *pp.V87Planet) (l0, b0 unit.Angle) {
	λ0, _, R := solar.ApparentVSOP87(earth, m.jde)
	ΔR := unit.Angle(Δ / (R * base.AU))
	λH := λ0 + math.Pi + ΔR.Mul(β.Cos()*(λ0-λ).Sin())
	βH := ΔR * β
	return m.lib(λH, βH)
}
예제 #25
0
파일: apparent.go 프로젝트: soniakeys/meeus
// AberrationRonVondrak uses the Ron-Vondrák expression to compute corrections
// due to aberration for equatorial coordinates of an object.
func AberrationRonVondrak(α unit.RA, δ unit.Angle, jd float64) (Δα unit.HourAngle, Δδ unit.Angle) {
	T := base.J2000Century(jd)
	r := &rv{
		T:  T,
		L2: 3.1761467 + 1021.3285546*T,
		L3: 1.7534703 + 628.3075849*T,
		L4: 6.2034809 + 334.0612431*T,
		L5: 0.5995465 + 52.9690965*T,
		L6: 0.8740168 + 21.3299095*T,
		L7: 5.4812939 + 7.4781599*T,
		L8: 5.3118863 + 3.8133036*T,
		Lp: 3.8103444 + 8399.6847337*T,
		D:  5.1984667 + 7771.3771486*T,
		Mp: 2.3555559 + 8328.6914289*T,
		F:  1.6279052 + 8433.4661601*T,
	}
	var Xp, Yp, Zp float64
	// sum smaller terms first
	for i := 35; i >= 0; i-- {
		x, y, z := rvTerm[i](r)
		Xp += x
		Yp += y
		Zp += z
	}
	sα, cα := α.Sincos()
	sδ, cδ := δ.Sincos()
	// (23.4) p. 156
	Δα = unit.HourAngle((Yp*cα - Xp*sα) / (c * cδ))
	Δδ = unit.Angle(-((Xp*cα+Yp*sα)*sδ - Zp*cδ) / c)
	return
}
예제 #26
0
파일: coord.go 프로젝트: soniakeys/meeus
// EclToEq converts ecliptic coordinates to equatorial coordinates.
func (eq *Equatorial) EclToEq(ecl *Ecliptic, ε *Obliquity) *Equatorial {
	sβ, cβ := ecl.Lat.Sincos()
	sλ, cλ := ecl.Lon.Sincos()
	eq.RA = unit.RAFromRad(math.Atan2(sλ*ε.C-(sβ/cβ)*ε.S, cλ)) // (13.3) p. 93
	eq.Dec = unit.Angle(math.Asin(sβ*ε.C + cβ*ε.S*sλ))         // (13.4) p. 93
	return eq
}
예제 #27
0
파일: precess.go 프로젝트: soniakeys/meeus
// NewPrecessor constructs a Precessor object and initializes it to precess
// coordinates from epochFrom to epochTo.
func NewPrecessor(epochFrom, epochTo float64) *Precessor {
	// (21.2) p. 134
	ζCoeff := ζt
	zCoeff := zt
	θCoeff := θt
	if epochFrom != 2000 {
		T := (epochFrom - 2000) * .01
		ζCoeff = []float64{
			base.Horner(T, ζT...),
			0.30188*s - 0.000344*s*T,
			0.017998 * s}
		zCoeff = []float64{
			base.Horner(T, zT...),
			1.09468*s + 0.000066*s*T,
			0.018203 * s}
		θCoeff = []float64{
			base.Horner(T, θT...),
			-0.42665*s - 0.000217*s*T,
			-0.041833 * s}
	}
	t := (epochTo - epochFrom) * .01
	p := &Precessor{
		ζ: unit.RA(base.Horner(t, ζCoeff...) * t),
		z: unit.Angle(base.Horner(t, zCoeff...) * t),
	}
	θ := base.Horner(t, θCoeff...) * t
	p.sθ, p.cθ = math.Sincos(θ)
	return p
}
예제 #28
0
파일: precess.go 프로젝트: soniakeys/meeus
// Position precesses equatorial coordinates from one epoch to another,
// including proper motions.
//
// If proper motions are not to be considered or are not applicable, pass 0, 0
// for mα, mδ
//
// Both eqFrom and eqTo must be non-nil, although they may point to the same
// struct.  EqTo is returned for convenience.
func Position(eqFrom, eqTo *coord.Equatorial, epochFrom, epochTo float64, mα unit.HourAngle, mδ unit.Angle) *coord.Equatorial {
	p := NewPrecessor(epochFrom, epochTo)
	t := epochTo - epochFrom
	eqTo.RA = unit.RAFromRad(eqFrom.RA.Rad() + mα.Rad()*t)
	eqTo.Dec = eqFrom.Dec + mδ*unit.Angle(t)
	return p.Precess(eqTo, eqTo)
}
예제 #29
0
파일: kepler.go 프로젝트: soniakeys/meeus
// Kepler1 solves Kepler's equation by iteration.
//
// The iterated formula is
//
//	E1 = M + e * sin(E0)
//
// Argument e is eccentricity, M is mean anomaly,
// places is the desired number of decimal places in the result.
//
// Result E is eccentric anomaly.
//
// For some vaues of e and M it will fail to converge and the
// function will return an error.
func Kepler1(e float64, M unit.Angle, places int) (E unit.Angle, err error) {
	f := func(E0 float64) float64 {
		return M.Rad() + e*math.Sin(E0) // (30.5) p. 195
	}
	ea, err := iterate.DecimalPlaces(f, M.Rad(), places, places*5)
	return unit.Angle(ea), err
}
예제 #30
0
func ExampleIlluminated_venus() {
	// Example 41.a, p. 284.
	k := base.Illuminated(unit.Angle(math.Acos(.29312)))
	fmt.Printf("%.3f\n", k)
	// Output:
	// 0.647
}