def calculate_phase_angle(self, t_struct): """ Calculates the phase angle of the planet, in degrees. """ # For the moon, we will approximate phase angle by calculating the # elongation of the moon relative to the sun. This is accurate to within # about 1%. if self.id == planet_enum.MOON: moon_ra_dec = self.calculate_lunar_geocentric_location(t_struct) moon = gc_get_instance(moon_ra_dec.ra, moon_ra_dec.dec) sun_coords = hc_get_instance( t_struct=t_struct, planet=Planet( planet_enum.SUN, res[planet_enum.SUN][0], res[planet_enum.SUN][1], res[planet_enum.SUN][2] ), ) sun_ra_dec = calculate_ra_dec_dist(sun_coords) sun = gc_get_instance(sun_ra_dec.ra, sun_ra_dec.dec) return 180.0 - Geometry.radians_to_degrees(math.acos(sun.x * moon.x + sun.y * moon.y + sun.z * moon.z)) # First, determine position in the solar system. planet_coords = hc_get_instance(planet=self, t_struct=t_struct) # Second, determine position relative to Earth earth_coords = hc_get_instance( t_struct=t_struct, planet=Planet(planet_enum.SUN, res[planet_enum.SUN][0], res[planet_enum.SUN][1], res[planet_enum.SUN][2]), ) earth_distance = planet_coords.distance_from(earth_coords) # Finally, calculate the phase of the body. phase = Geometry.radians_to_degrees( math.acos( ( earth_distance * earth_distance + planet_coords.radius * planet_coords.radius - earth_coords.radius * earth_coords.radius ) / (2.0 * earth_distance * planet_coords.radius) ) ) return phase
def calculate_lunar_geocentric_location(self, t_struct): """ Calculate the geocentric right ascension and declination of the moon using an approximation as described on page D22 of the 2008 Astronomical Almanac All of the variables in this method use the same names as those described in the text: lambda = Ecliptic longitude (degrees) beta = Ecliptic latitude (degrees) pi = horizontal parallax (degrees) r = distance (Earth radii) NOTE: The text does not give a specific time period where the approximation is valid, but it should be valid through at least 2009. """ # First, calculate the number of Julian centuries from J2000.0. t = (calculate_julian_day(t_struct) - 2451545.0) / 36525.0 # Second, calculate the approximate geocentric orbital elements. lambda_val = ( 218.32 + 481267.881 * t + 6.29 * math.sin(Geometry.degrees_to_radians(135.0 + 477198.87 * t)) - 1.27 * math.sin(Geometry.degrees_to_radians(259.3 - 413335.36 * t)) + 0.66 * math.sin(Geometry.degrees_to_radians(235.7 + 890534.22 * t)) + 0.21 * math.sin(Geometry.degrees_to_radians(269.9 + 954397.74 * t)) - 0.19 * math.sin(Geometry.degrees_to_radians(357.5 + 35999.05 * t)) - 0.11 * math.sin(Geometry.degrees_to_radians(186.5 + 966404.03 * t)) ) beta = ( 5.13 * math.sin(Geometry.degrees_to_radians(93.3 + 483202.02 * t)) + 0.28 * math.sin(Geometry.degrees_to_radians(228.2 + 960400.89 * t)) - 0.28 * math.sin(Geometry.degrees_to_radians(318.3 + 6003.15 * t)) - 0.17 * math.sin(Geometry.degrees_to_radians(217.6 - 407332.21 * t)) ) # Third, convert to RA and Dec. l = math.cos(Geometry.degrees_to_radians(beta)) * math.cos(Geometry.degrees_to_radians(lambda_val)) m = 0.9175 * math.cos(Geometry.degrees_to_radians(beta)) * math.sin( Geometry.degrees_to_radians(lambda_val) ) - 0.3978 * math.sin(Geometry.degrees_to_radians(beta)) n = 0.3978 * math.cos(Geometry.degrees_to_radians(beta)) * math.sin( Geometry.degrees_to_radians(lambda_val) ) + 0.9175 * math.sin(Geometry.degrees_to_radians(beta)) ra = Geometry.radians_to_degrees(Geometry.mod_2_pi(math.atan2(m, l))) dec = Geometry.radians_to_degrees(math.asin(n)) return RaDec(ra, dec)
def get_magnitude(self, t_struct): """ Calculates the planet's magnitude for the given date. """ if self.id == planet_enum.SUN: return -27.0 if self.id == planet_enum.MOON: return -10.0 # First, determine position in the solar system. planet_coords = hc_get_instance(planet=self, t_struct=t_struct) # Second, determine position relative to Earth earth_coords = hc_get_instance( t_struct=t_struct, planet=Planet(planet_enum.SUN, res[planet_enum.SUN][0], res[planet_enum.SUN][1], res[planet_enum.SUN][2]), ) earth_distance = planet_coords.distance_from(earth_coords) # Third, calculate the phase of the body. phase = Geometry.radians_to_degrees( math.acos( ( earth_distance * earth_distance + planet_coords.radius * planet_coords.radius - earth_coords.radius * earth_coords.radius ) / (2.0 * earth_distance * planet_coords.radius) ) ) p = phase / 100.0 # Normalized phase angle # Finally, calculate the magnitude of the body. mag = -100.0 # Apparent visual magnitude if self.id == planet_enum.MERCURY: mag = -0.42 + (3.80 - (2.73 - 2.00 * p) * p) * p elif self.id == planet_enum.VENUS: mag = -4.40 + (0.09 + (2.39 - 0.65 * p) * p) * p elif self.id == planet_enum.MARS: mag = -1.52 + 1.6 * p elif self.id == planet_enum.JUPITER: mag = -9.40 + 0.5 * p elif self.id == planet_enum.SATURN: mag = -8.75 elif self.id == planet_enum.URANUS: mag = -7.19 elif self.id == planet_enum.NEPTUNE: mag = -6.87 elif self.id == planet_enum.PLUTO: mag = -1.0 else: mag = 100 return mag + 5.0 * math.log10(planet_coords.radius * earth_distance)
def calculate_phase_angle(self, t_struct): ''' Calculates the phase angle of the planet, in degrees. ''' # For the moon, we will approximate phase angle by calculating the # elongation of the moon relative to the sun. This is accurate to within # about 1%. if self.id == planet_enum.MOON: moon_ra_dec = self.calculate_lunar_geocentric_location(t_struct) moon = gc_get_instance(moon_ra_dec.ra, moon_ra_dec.dec) sun_coords = hc_get_instance(t_struct=t_struct, planet=Planet(planet_enum.SUN, res[planet_enum.SUN][0], res[planet_enum.SUN][1], res[planet_enum.SUN][2])) sun_ra_dec = calculate_ra_dec_dist(sun_coords) sun = gc_get_instance(sun_ra_dec.ra, sun_ra_dec.dec) return 180.0 - \ Geometry.radians_to_degrees(math.acos(sun.x * moon.x + sun.y * moon.y + sun.z * moon.z)) # First, determine position in the solar system. planet_coords = hc_get_instance(planet=self, t_struct=t_struct) # Second, determine position relative to Earth earth_coords = hc_get_instance(t_struct=t_struct, planet=Planet(planet_enum.SUN, res[planet_enum.SUN][0], res[planet_enum.SUN][1], res[planet_enum.SUN][2])) earth_distance = planet_coords.distance_from(earth_coords) # Finally, calculate the phase of the body. phase = Geometry.radians_to_degrees(\ math.acos((earth_distance * earth_distance + \ planet_coords.radius * planet_coords.radius - \ earth_coords.radius * earth_coords.radius) / \ (2.0 * earth_distance * planet_coords.radius))) return phase
def calculate_lunar_geocentric_location(self, t_struct): ''' Calculate the geocentric right ascension and declination of the moon using an approximation as described on page D22 of the 2008 Astronomical Almanac All of the variables in this method use the same names as those described in the text: lambda = Ecliptic longitude (degrees) beta = Ecliptic latitude (degrees) pi = horizontal parallax (degrees) r = distance (Earth radii) NOTE: The text does not give a specific time period where the approximation is valid, but it should be valid through at least 2009. ''' # First, calculate the number of Julian centuries from J2000.0. t = ((calculate_julian_day(t_struct) - 2451545.0) / 36525.0) # Second, calculate the approximate geocentric orbital elements. lambda_val = 218.32 + 481267.881 * t + 6.29 \ * math.sin(Geometry.degrees_to_radians(135.0 + 477198.87 * t)) - 1.27 \ * math.sin(Geometry.degrees_to_radians(259.3 - 413335.36 * t)) + 0.66 \ * math.sin(Geometry.degrees_to_radians(235.7 + 890534.22 * t)) + 0.21 \ * math.sin(Geometry.degrees_to_radians(269.9 + 954397.74 * t)) - 0.19 \ * math.sin(Geometry.degrees_to_radians(357.5 + 35999.05 * t)) - 0.11 \ * math.sin(Geometry.degrees_to_radians(186.5 + 966404.03 * t)) beta = 5.13 \ * math.sin(Geometry.degrees_to_radians(93.3 + 483202.02 * t)) + 0.28 \ * math.sin(Geometry.degrees_to_radians(228.2 + 960400.89 * t)) - 0.28 \ * math.sin(Geometry.degrees_to_radians(318.3 + 6003.15 * t)) - 0.17 \ * math.sin(Geometry.degrees_to_radians(217.6 - 407332.21 * t)) # Third, convert to RA and Dec. l = math.cos(Geometry.degrees_to_radians(beta)) \ * math.cos(Geometry.degrees_to_radians(lambda_val)) m = 0.9175 * math.cos(Geometry.degrees_to_radians(beta)) \ * math.sin(Geometry.degrees_to_radians(lambda_val)) - 0.3978 \ * math.sin(Geometry.degrees_to_radians(beta)) n = 0.3978 * math.cos(Geometry.degrees_to_radians(beta)) \ * math.sin(Geometry.degrees_to_radians(lambda_val)) + 0.9175 \ * math.sin(Geometry.degrees_to_radians(beta)) ra = Geometry.radians_to_degrees(Geometry.mod_2_pi(math.atan2(m, l))) dec = Geometry.radians_to_degrees(math.asin(n)) return RaDec(ra, dec)
def get_magnitude(self, t_struct): ''' Calculates the planet's magnitude for the given date. ''' if self.id == planet_enum.SUN: return -27.0 if self.id == planet_enum.MOON: return -10.0 # First, determine position in the solar system. planet_coords = hc_get_instance(planet=self, t_struct=t_struct) # Second, determine position relative to Earth earth_coords = hc_get_instance(t_struct=t_struct, planet=Planet(planet_enum.SUN, res[planet_enum.SUN][0], res[planet_enum.SUN][1], res[planet_enum.SUN][2])) earth_distance = planet_coords.distance_from(earth_coords) # Third, calculate the phase of the body. phase = Geometry.radians_to_degrees(\ math.acos((earth_distance * earth_distance + \ planet_coords.radius * planet_coords.radius - \ earth_coords.radius * earth_coords.radius) / \ (2.0 * earth_distance * planet_coords.radius))) p = phase/100.0 # Normalized phase angle # Finally, calculate the magnitude of the body. mag = -100.0 # Apparent visual magnitude if self.id == planet_enum.MERCURY: mag = -0.42 + (3.80 - (2.73 - 2.00 * p) * p) * p elif self.id == planet_enum.VENUS: mag = -4.40 + (0.09 + (2.39 - 0.65 * p) * p) * p elif self.id == planet_enum.MARS: mag = -1.52 + 1.6 * p elif self.id == planet_enum.JUPITER: mag = -9.40 + 0.5 * p elif self.id == planet_enum.SATURN: mag = -8.75 elif self.id == planet_enum.URANUS: mag = -7.19 elif self.id == planet_enum.NEPTUNE: mag = -6.87 elif self.id == planet_enum.PLUTO: mag = -1.0 else: mag = 100 return (mag + 5.0 * math.log10(planet_coords.radius * earth_distance))
def calculate_hour_angle(self, altitude, latitude, declination): ''' Calculates the hour angle of a given declination for the given location. This is a helper application for the rise and set calculations. Its probably not worth using as a general purpose method. All values are in degrees. This method calculates the hour angle from the meridian using the following equation from the Astronomical Almanac (p487): cos ha = (sin alt - sin lat * sin dec) / (cos lat * cos dec) ''' alt_rads = Geometry.degrees_to_radians(altitude) lat_rads = Geometry.degrees_to_radians(latitude) dec_rads = Geometry.degrees_to_radians(declination) cos_ha = (math.sin(alt_rads) - math.sin(lat_rads) * math.sin(dec_rads)) / \ (math.cos(lat_rads) * math.cos(dec_rads)) return Geometry.radians_to_degrees(math.acos(cos_ha))
def calculate_hour_angle(self, altitude, latitude, declination): """ Calculates the hour angle of a given declination for the given location. This is a helper application for the rise and set calculations. Its probably not worth using as a general purpose method. All values are in degrees. This method calculates the hour angle from the meridian using the following equation from the Astronomical Almanac (p487): cos ha = (sin alt - sin lat * sin dec) / (cos lat * cos dec) """ alt_rads = Geometry.degrees_to_radians(altitude) lat_rads = Geometry.degrees_to_radians(latitude) dec_rads = Geometry.degrees_to_radians(declination) cos_ha = (math.sin(alt_rads) - math.sin(lat_rads) * math.sin(dec_rads)) / ( math.cos(lat_rads) * math.cos(dec_rads) ) return Geometry.radians_to_degrees(math.acos(cos_ha))