Алгоритм фазы Луны / Луны - PullRequest
33 голосов
/ 27 марта 2010

Кто-нибудь знает алгоритм для расчета фазы или возраста луны на определенную дату или для нахождения дат для новых / полных лун в данном году?

Гугл говорит мне, что ответ есть в какой-то книге по астрономии, но я действительно не хочу покупать целую книгу, когда мне нужна только одна страница.

Обновление:

Я должен был уточнить свое утверждение о поискенемного лучше.Я нашел решения, которые работали только в течение некоторого времени (например, 1900-е годы);и решения на основе Trig, которые были бы более вычислительно дорогими, чем я хотел бы.

У С. Лотта в его книге по Python есть несколько алгоритмов для вычисления Пасхи по данному году, большинство из которых содержат менее десяти строк кода, а некоторые работают для всех дней в григорианском календаре.Поиск полнолуния в марте - ключевой момент нахождения Пасхи, поэтому я решил, что должен быть алгоритм, который не требует триггера и работает для всех дат в григорианском календаре.

Ответы [ 8 ]

16 голосов
/ 28 марта 2010

Я перенес некоторый код в Python для этого некоторое время назад. Я собирался просто дать ссылку на него, но оказалось, что в это время он упал с интернета, поэтому мне пришлось стряхнуть его и загрузить снова. См. moon.py , полученный из Moontool Джона Уокера .

Я не могу найти ссылку на это, для какого времени это точно, но кажется, что авторы были довольно строгими. Это означает, что да, он использует trig, но я не могу себе представить, какого черта вы будете использовать это для того, чтобы сделать это вычислительно запретительным. Затраты на вызов функции Python, вероятно, превышают стоимость операций триггера. Компьютеры довольно быстро разбираются.

Алгоритмы, используемые в коде, взяты из следующих источников:

Меус, Жан. Астрономические Алгоритмы. Ричмонд: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Обязательный; если вы покупаете только одну книгу, убедитесь, что она эта. Алгоритмы представлены математически, а не как компьютерные программы, но исходный код, реализующий многие из алгоритмов в книге, можно заказать отдельно от издателя в QuickBasic, Turbo Pascal или C. Meeus предоставляет множество проработанных примеров вычислений, которые необходимы для отладки. ваш код, и часто представляет несколько алгоритмов с различными компромиссами между точностью, скоростью, сложностью и долгосрочной (века и тысячелетия) достоверностью.

Даффетт-Смит, Питер. Практическая астрономия с вашим калькулятором. 3-е изд. Кембридж: издательство Кембриджского университета, 1981. ISBN 0-521-28411-2.

Несмотря на слово «Калькулятор» в заголовке; Это ценный справочник, если вы заинтересованы в разработке программного обеспечения, которое рассчитывает положения планет, орбиты, затмения и тому подобное. Предоставляется больше исходной информации, чем в Миусе, что помогает тем, кто еще не разбирается в астрономии, изучать часто сбивающую с толку терминологию. Приведенные алгоритмы являются более простыми и менее точными, чем те, которые предоставляет Meeus, но подходят для большинства практических работ.

11 голосов
/ 07 сентября 2013

Если вы похожи на меня, вы пытаетесь быть осторожным программистом. Таким образом, это заставляет вас нервничать, когда вы видите случайный код, разбросанный по Интернету, который призван решить сложную астрономическую проблему, но не объясняет, почему решение является правильным.

Вы считаете, что должны существовать авторитетные источники, такие как книги , которые содержат тщательные и полные решения. Например:

Миус, Жан. Астрономические Алгоритмы. Ричмонд: Willmann-Bell, 1991. ISBN 0-943396-35-2.

Даффетт-Смит, Питер. Практическая астрономия с вашим калькулятором. 3-е изд. Кембридж: Издательство Кембриджского университета, 1981. ISBN 0-521-28411-2.

Вы доверяете широко используемым, хорошо протестированным библиотекам с открытым исходным кодом, в которых можно исправить свои ошибки (в отличие от статических веб-страниц). Итак, вот решение Python для вашего вопроса, основанное на библиотеке PyEphem с использованием интерфейса 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)

Возвращает

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 голосов
/ 27 марта 2010
7 голосов
/ 28 марта 2010

Кроме того, pyephem - астрономические процедуры научного уровня [ PyPI ], который является пакетом Python, но имеет вычислительные возможности в C и что говорит говорит

Точность <0,05 "от -1369 до +2950. <Br /> Использует методы поиска в таблице для ограничения вызовов тригонометрических функций.

2 голосов
/ 23 августа 2015

Pyephem по умолчанию использует всемирное координированное время (UTC). Я хотел программу, которая генерировала бы список полнолуний, которые были бы точны в тихом часовом поясе. Приведенный ниже код будет рассчитывать полные луны для данного года, а затем скорректировать его с помощью метода ephem.localtime () для калибровки в нужный часовой пояс. Похоже, что он также правильно учитывает переход на летнее время. Спасибо Ричарду, этот код похож на то, что он написал.

#!/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)

Приведенный выше код вернет:

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']
0 голосов
/ 08 апреля 2010

Если вам не нужна высокая точность, вы всегда можете (ab) использовать класс лунного (или лунно-солнечного) календаря (например, HijriCalendar или ChineseLunisolarCalendar в Microsoft .NET) для расчета (приблизительной) фазы луны любой даты, поскольку свойство календаря "день месяца", являющееся лунным (или лунно-солнечным) календарным днем, всегда соответствует фазе луны (например, день 1 - это новолуние, день 15 это полная луна и т. д.)

0 голосов
/ 31 марта 2010

Я знаю, что вы ищете Python, но если вы понимаете C #, существует проект с открытым исходным кодом, который называется Chronos XP , который делает это очень хорошо.

0 голосов
/ 27 марта 2010

Быстрый гугл показал это .

...