web-dev-qa-db-fra.com

Algorithme de phase lunaire/lunaire

Est-ce que quelqu'un connaît un algorithme permettant soit de calculer la phase de la lune ou son âge à une date donnée, soit de trouver les dates des nouvelles ou des pleines lunes au cours d'une année donnée?

Googling me dit que la réponse se trouve dans un livre d'astronomie, mais je ne veux pas vraiment acheter un livre entier quand je n'ai besoin que d'une seule page.

Mettre à jour:

J'aurais dû nuancer un peu mieux ma déclaration sur Google. J'ai trouvé des solutions qui ne fonctionnaient que sur un sous-ensemble de temps (comme dans les années 1900); et les solutions à base de trigonomètres qui seraient plus coûteuses en calculs que je ne le souhaiterais. 

Dans son livre Python, S Lott utilise plusieurs algorithmes pour calculer Pâques au cours d’une année donnée. La plupart ne comportent pas plus de dix lignes de code et certains fonctionnent pour tous les jours du calendrier grégorien. Trouver la pleine lune en mars est un élément clé de la recherche de Pâques. J'ai donc pensé qu'il devrait exister un algorithme ne nécessitant pas de trig et fonctionnant à toutes les dates du calendrier grégorien.

32
Scott Bailey

J'ai porté du code vers Python pour cela il y a quelque temps. J'allais simplement créer un lien vers ce site, mais il s'est avéré qu'il est tombé du Web entre-temps. J'ai donc dû le dépoussiérer et le télécharger à nouveau. Voir moon.py qui est dérivé de moontool de John Walker .

Je ne trouve pas de référence à ce sujet, mais les auteurs étaient assez rigoureux. Ce qui signifie que oui, il utilise trig, mais je ne peux pas imaginer comment diable vous utiliseriez ceci car cela rendrait le calcul prohibitif. La surcharge des appels de fonction Python est probablement supérieure au coût des opérations trig. Les ordinateurs sont assez rapides en informatique.

Les algorithmes utilisés dans le code sont tirés des sources suivantes:

Meeus, Jean. Algorithmes Astronomiques. Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Quelque chose qu'il FAUT posséder; si vous n'achetez qu'un seul livre, assurez-vous que c'est celui-ci. Les algorithmes sont présentés mathématiquement et non comme des programmes informatiques, mais le code source implémentant de nombreux algorithmes du livre peut être commandé séparément de l'éditeur dans QuickBasic, Turbo Pascal ou C. Meeus fournit de nombreux exemples travaillés de calculs essentiels au débogage. votre code et présente fréquemment plusieurs algorithmes avec des compromis différents en termes de précision, de rapidité, de complexité et de validité à long terme (siècles et millénaires).

Duffett-Smith, Peter. Astronomie Pratique Avec Votre Calculatrice. 3ème éd. Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.

Malgré le calculateur de mots dans le titre; C’est une référence précieuse si vous souhaitez développer un logiciel permettant de calculer les positions planétaires, les orbites, les éclipses, etc. Meeus fournit davantage d’informations d’arrière-plan, ce qui aide ceux qui ne sont pas déjà familiarisés avec l’astronomie à apprendre la terminologie souvent déroutante. Les algorithmes donnés sont plus simples et moins précis que ceux fournis par Meeus, mais conviennent à la plupart des travaux pratiques.

16
keturn
11
Jack

Si vous êtes comme moi, vous essayez d'être un programmeur prudent. Cela vous rend donc nerveux lorsque vous voyez du code aléatoire dispersé sur Internet qui prétend résoudre un problème astronomique complexe, mais n'explique pas pourquoi la solution est correcte.

Vous estimez qu'il doit exister des sources faisant autorité, telles que books , qui contiennent des solutions minutieuses et complètes. Par exemple:

Meeus, Jean. Algorithmes Astronomiques. Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Duffett-Smith, Peter. Astronomie Pratique Avec Votre Calculatrice. 3ème éd. Cambridge: Cambridge University Press, 1981. ISBN 0-521-28411-2.

Vous faites confiance aux bibliothèques open source largement utilisées, bien testées et dont les erreurs peuvent être corrigées (contrairement aux pages Web statiques). Voici donc une solution Python à votre question basée sur la bibliothèque PyEphem , à l’aide de l’interface Phases of the Moon .

#!/usr/bin/python
import datetime
import ephem

def get_phase_on_day(year,month,day):
  """Returns a floating-point number from 0-1. where 0=new, 0.5=full, 1=new"""
  #Ephem stores its date numbers as floating points, which the following uses
  #to conveniently extract the percent time between one new moon and the next
  #This corresponds (somewhat roughly) to the phase of the moon.

  #Use Year, Month, Day as arguments
  date=ephem.Date(datetime.date(year,month,day))

  nnm = ephem.next_new_moon    (date)
  pnm = ephem.previous_new_moon(date)

  lunation=(date-pnm)/(nnm-pnm)

  #Note that there is a ephem.Moon().phase() command, but this returns the
  #percentage of the moon which is illuminated. This is not really what we want.

  return lunation

def get_moons_in_year(year):
  """Returns a list of the full and new moons in a year. The list contains tuples
of either the form (DATE,'full') or the form (DATE,'new')"""
  moons=[]

  date=ephem.Date(datetime.date(year,01,01))
  while date.datetime().year==year:
    date=ephem.next_full_moon(date)
    moons.append( (date,'full') )

  date=ephem.Date(datetime.date(year,01,01))
  while date.datetime().year==year:
    date=ephem.next_new_moon(date)
    moons.append( (date,'new') )

  #Note that previous_first_quarter_moon() and previous_last_quarter_moon()
  #are also methods

  moons.sort(key=lambda x: x[0])

  return moons

print get_phase_on_day(2013,1,1)

print get_moons_in_year(2013)

Cela retourne

0.632652265318

[(2013/1/11 19:43:37, 'new'), (2013/1/27 04:38:22, 'full'), (2013/2/10 07:20:06, 'new'), (2013/2/25 20:26:03, 'full'), (2013/3/11 19:51:00, 'new'), (2013/3/27 09:27:18, 'full'), (2013/4/10 09:35:17, 'new'), (2013/4/25 19:57:06, 'full'), (2013/5/10 00:28:22, 'new'), (2013/5/25 04:24:55, 'full'), (2013/6/8 15:56:19, 'new'), (2013/6/23 11:32:15, 'full'), (2013/7/8 07:14:16, 'new'), (2013/7/22 18:15:31, 'full'), (2013/8/6 21:50:40, 'new'), (2013/8/21 01:44:35, 'full'), (2013/9/5 11:36:07, 'new'), (2013/9/19 11:12:49, 'full'), (2013/10/5 00:34:31, 'new'), (2013/10/18 23:37:39, 'full'), (2013/11/3 12:49:57, 'new'), (2013/11/17 15:15:44, 'full'), (2013/12/3 00:22:22, 'new'), (2013/12/17 09:28:05, 'full'), (2014/1/1 11:14:10, 'new'), (2014/1/16 04:52:10, 'full')]
11
Richard

En outre, pyephem - routines d'astronomie de niveau scientifique } _ [ PyPI ], qui est un package Python mais a le intestins de calcul en C , et que fait dire

Précision <0,05 "de -1369 à +2950.
Utilise des techniques de consultation de table pour limiter les appels aux fonctions trigonométriques.

7
keturn

Pyephem utilise par défaut le temps universel coordonné (UTC). Je voulais un programme qui générerait une liste de pleines lunes qui seraient précises dans le fuseau horaire du Pacifique. Le code ci-dessous calculera le nombre total de lunes pour une année donnée, puis l’ajustera à l’aide de la méthode ephem.localtime () pour effectuer l’étalonnage sur le fuseau horaire souhaité. Il semble également que l’heure avancée soit correctement prise en compte. Merci à Richard, ce code est similaire à ce qu'il avait écrit.

#!/usr/bin/python
import datetime
import ephem
import os
import time

# Set time zone to pacific
os.environ['TZ'] = 'US/Pacific'
time.tzset()

print("Time zone calibrated to", os.environ['TZ'])

def get_full_moons_in_year(year):
    """
    Generate a list of full moons for a given year calibrated to the local time zone
    :param year: year to determine the list of full moons
    :return: list of dates as strings in the format YYYY-mm-dd
    """
    moons = []

    date = ephem.Date(datetime.date(year - 1, 12, 31))
    end_date = ephem.Date(datetime.date(year + 1, 1, 1))

    while date <= end_date:
        date = ephem.next_full_moon(date)

        # Convert the moon dates to the local time zone, add to list if moon date still falls in desired year
        local_date = ephem.localtime(date)
        if local_date.year == year:
            # Append the date as a string to the list for easier comparison later
            moons.append(local_date.strftime("%Y-%m-%d"))

    return moons

moons = get_full_moons_in_year(2015)
print(moons)

Le code ci-dessus retournera:

Time zone calibrated to US/Pacific
['2015-01-04', '2015-02-03', '2015-03-05', '2015-04-04', '2015-05-03', '2015-06-02', '2015-07-01', '2015-07-31', '2015-08-29', '2015-09-27', '2015-10-27', '2015-11-25', '2015-12-25']
2
Victor Rendina

Je sais que vous recherchez Python, mais si vous comprenez bien C #, il existe un projet open source appelé Chronos XP qui le fait très bien.

0
Repo Man