Beispiel #1
0
// ApparentEccentricity returns apparent eccenticity of a binary star
// given true orbital elements.
//
//  e is eccentricity of the true orbit
//  i is inclination relative to the line of sight
//  ω is longitude of periastron
func ApparentEccentricity(e float64, i, ω unit.Angle) float64 {
	ci := i.Cos()
	sω, cω := ω.Sincos()
	A := (1 - e*e*cω*cω) * ci * ci
	B := e * e * sω * cω * ci
	C := 1 - e*e*sω*sω
	d := A - C
	sD := math.Sqrt(d*d + 4*B*B)
	return math.Sqrt(2 * sD / (A + C + sD))
}
Beispiel #2
0
// 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
}
Beispiel #3
0
func (m *moon) pa(λ, β, b unit.Angle) unit.Angle {
	V := m.Ω + m.Δψ + m.σ.Div(sI)
	sV, cV := V.Sincos()
	sIρ, cIρ := (_I + m.ρ).Sincos()
	X := sIρ * sV
	Y := sIρ*cV*m.cε - cIρ*m.sε
	ω := math.Atan2(X, Y)
	α, _ := coord.EclToEq(λ+m.Δψ, β, m.sε, m.cε)
	P := unit.Angle(math.Asin(math.Hypot(X, Y) * math.Cos(α.Rad()-ω) / b.Cos()))
	if P < 0 {
		P += 2 * math.Pi
	}
	return P
}
Beispiel #4
0
// Error returns an error angle of three nearly co-linear points.
//
// For the line defined by r1, d1, r2, d2, the result is the anglular distance
// between that line and r0, d0.
//
// Algorithm by Meeus.
func Error(r1, d1, r2, d2, r0, d0 unit.Angle) unit.Angle {
	sr1, cr1 := r1.Sincos()
	sd1, cd1 := d1.Sincos()
	sr2, cr2 := r2.Sincos()
	sd2, cd2 := d2.Sincos()
	X1 := cd1 * cr1
	X2 := cd2 * cr2
	Y1 := cd1 * sr1
	Y2 := cd2 * sr2
	Z1 := sd1
	Z2 := sd2
	A := Y1*Z2 - Z1*Y2
	B := Z1*X2 - X1*Z2
	C := X1*Y2 - Y1*X2
	m := r0.Tan()
	n := d0.Tan() / r0.Cos()
	return unit.Angle(math.Asin((A + B*m + C*n) /
		(math.Sqrt(A*A+B*B+C*C) * math.Sqrt(1+m*m+n*n))))
}
Beispiel #5
0
// Smallest finds the smallest circle containing three points.
//
// Arguments should represent coordinates in right ascension and declination
// or longitude and latitude.  Result Δ is the diameter of the circle, typeI
// is true if solution is of type I.
//
//	type I   Two points on circle, one interior.
//	type II  All three points on circle.
func Smallest(r1, d1, r2, d2, r3, d3 unit.Angle) (Δ unit.Angle, typeI bool) {
	// Using haversine formula, but reimplementing SepHav here to reuse
	// the computed cosines.
	cd1 := d1.Cos()
	cd2 := d2.Cos()
	cd3 := d3.Cos()
	a := 2 * math.Asin(math.Sqrt(base.Hav(d2-d1)+cd1*cd2*base.Hav(r2-r1)))
	b := 2 * math.Asin(math.Sqrt(base.Hav(d3-d2)+cd2*cd3*base.Hav(r3-r2)))
	c := 2 * math.Asin(math.Sqrt(base.Hav(d1-d3)+cd3*cd1*base.Hav(r1-r3)))
	if b > a {
		a, b = b, a
	}
	if c > a {
		a, c = c, a
	}
	if a*a >= b*b+c*c {
		return unit.Angle(a), true
	}
	// (20.1) p. 128
	return unit.Angle(2 * a * b * c /
		math.Sqrt((a+b+c)*(a+b-c)*(b+c-a)*(a+c-b))), false
}
Beispiel #6
0
// Radius returns radius distance r for given eccentric anomaly E.
//
// Argument e is eccentricity, a is semimajor axis.
//
// Result unit is the unit of semimajor axis a (typically AU.)
func Radius(E unit.Angle, e, a float64) float64 {
	// (30.2) p. 195
	return a * (1 - e*E.Cos())
}
Beispiel #7
0
// Hav implements the haversine trigonometric function.
//
// See https://en.wikipedia.org/wiki/Haversine_formula.
func Hav(a unit.Angle) float64 {
	// (17.5) p. 115
	return .5 * (1 - a.Cos())
}
Beispiel #8
0
// SepHav returns the angular separation between two celestial bodies.
//
// The algorithm uses the haversine function and is superior to the naïve
// algorithm of the Sep function.
func SepHav(r1, d1, r2, d2 unit.Angle) unit.Angle {
	// using (17.5) p. 115
	return unit.Angle(2 * math.Asin(math.Sqrt(base.Hav(d2-d1)+
		d1.Cos()*d2.Cos()*base.Hav(r2-r1))))
}
Beispiel #9
0
// Illuminated returns the illuminated fraction of a body's disk.
//
// The illuminated body can be the Moon or a planet.
//
// Argument i is the phase angle.
func Illuminated(i unit.Angle) float64 {
	// (41.1) p. 283, also (48.1) p. 345.
	return (1 + i.Cos()) * .5
}
Beispiel #10
0
// SaturnApparentPolar returns apparent polar semidiameter of Saturn
// at specified distance.
//
// Argument Δ must be observer-Saturn distance in AU.  Argument B is
// Saturnicentric latitude of the observer as given by function saturnring.UB()
// for example.
func SaturnApparentPolar(Δ float64, B unit.Angle) unit.Angle {
	k := (SaturnPolar.Rad() / SaturnEquatorial.Rad())
	k = 1 - k*k
	cB := B.Cos()
	return SaturnEquatorial.Mul(math.Sqrt(1-k*cB*cB) / Δ)
}
Beispiel #11
0
// PhaseAngle2 computes the phase angle of a planet.
//
// Arguments L, B, R are heliocentric ecliptical coordinates of the planet.
// L0, R0 are longitude and radius for Earth, Δ is distance from Earth to
// the planet.  All distances in AU.
func PhaseAngle2(L, B unit.Angle, R float64, L0 unit.Angle, R0, Δ float64) unit.Angle {
	// (41.3) p. 283
	return unit.Angle(math.Acos((R - R0*B.Cos()*(L-L0).Cos()) / Δ))
}