def moon_elements(d): Ω = rev(125.1228 - 0.0529538083 * d) # Long asc. node i = 5.1454 # Inclination ω = rev(318.0634 + 0.1643573223 * d) # Arg. of perigee a = 60.2666 # Mean distance, # in Earth equatorial radii e = 0.054900 # Eccentricity M = rev(115.3654 + 13.0649929509 * d) # Mean anomaly return OrbitalElements(Ω, i, ω, a, e, M)
def sun_earth_elements(day_number): """ Why this function is named "sun_earth_elements": We're primarily concerned with the Earth-based observer, so we'll use these orbital elements to determine how the Sun moves through Earth's sky. Of course, outside of that frame it is more sensible to interpret these elements vice versa, with Earth moving around the Sun. """ ω = rev(282.9404 + 4.70935E-5 * day_number) # longitude of perihelion a = 1.000000 # mean_distance, in a.u. e = 0.016709 - 1.151E-9 * day_number # eccentricity M = rev(356.0470 + 0.9856002585 * day_number) # mean anomaly return (ω, a, e, M)
def moon_perturbation_arguments(mlon, moon_N, moon_ω, moon_M, M): Lm = moon_N + moon_ω + moon_M ( Ls, # Sun's mean longitude Ms, # Sun's mean anomaly Mm, # Moon's mean anomaly D, # Moon's mean elongation F, # Moon's argument of latitude ) = ( mlon, M, moon_M, rev(Lm - mlon), rev(Lm - moon_N), ) return (Ls, rev(Lm), Ms, Mm, D, F)
def ecliptic_anomaly_to_longitude( longitude_of_periapsis, angle_from_periapsis, ): """ Ecliptic longitude, sometimes written simply as "longitude", has its zero at the ascending node. For the Sun-Earth system, the ascending node is the vernal point (if I'm not mistaken!?). In contrast to longitude, the mean anomaly and true anomaly have their zero at periapsis. For the Sun-Earth system, the periapsis is perihelion. When we say "mean longitude" of the Sun, we mean "mean ecliptic longitude" with zero longitude at the vernal point. We are not referring to the terrestrial longitude or to the celestial longitude (also known as right ascension) that are zero at a meridian. We should also explain "mean longitude" vs. "longitude". The mean longitude progresses quite cyclically, while the (true) longitude goes elliptically. Both complete one revolution in the same time. True longitude measures the actual accelerating and decelerating position of a body. Mean longitude averages out the position over the whole revolution to measure out a fictitious steady motion. """ return rev(longitude_of_periapsis + angle_from_periapsis)
def test_cartesian3d_to_spherical_3(self): p = Cartesian3d( self.sun_alt_az_x, self.sun_alt_az_y, self.sun_alt_az_z, ).to_spherical() azimuth = rev(p.longitude + 180) self.assertAlmostEqual(azimuth, self.azimuth, places=4) self.assertAlmostEqual(p.latitude, self.altitude, places=4)
def test_rev_2(self): # Within the calculation of the mean anomaly M, # it is necessary to remove from the computed # value as many complete 360-degree revolutions # as we can. self.assertAlmostEqual( rev(-3135.934716), self.mean_anomaly, places=6, )
def sun_earth_celestial_to_alt_azimuth(mlon, Decl, RA, hours_UT, lat, lon): distance, altitude, azimuth = Spherical( 1.0, Decl, hours_to_arcdegrees(hour_angle( sidereal_time(GMST0(mlon), hours_UT, lon), arcdegrees_to_hours(RA), )), ).to_cartesian3d().decline_about_y(lat).to_spherical().as_tuple() azimuth = rev(azimuth + 180) return (altitude, azimuth)
def eccentric_anomaly_first_approximation(mean_anomaly, eccentricity): """ This truncated Taylor series is claimed accurate enough for a small eccentricity such as that of the Sun-Earth orbit (0.017). Properly the eccentric anomaly is the solution E of Kepler's equation in mean anomaly M and eccentricity e: M = E - e sin(E). Thanks to Paul Schlyter himself for clarifying this in a private email which, frankly, I have not yet fully analyzed. """ return rev( mean_anomaly + (180 / pi) * eccentricity * sin(mean_anomaly) * (1 + eccentricity * cos(mean_anomaly)))
def test_rev(self): r = rev(-442.00000000001827) # yes, this function has double precision self.assertAlmostEqual(r, 277.999999999982, places=10)
def GMST0(mean_longitude): """ Sidereal time (in other words, right ascension in hours) at the 00:00 meridian at Greenwich right now. """ return arcdegrees_to_hours(rev(mean_longitude + 180))
def hours_to_arcdegrees(hours): return rev(hours * 360 / 24.0)
def from_cartesian2d(cls, p): r = hypot(p.x, p.y) θ = rev(atan2(p.y, p.x)) self = cls.__new__(cls) self.__init__(r, θ) return self
def rotate(self, Δθ): return Polar(self.r, rev(self.θ + Δθ))