Я работаю над проектом для развлечения, где я представляю некоторые данные о сне географически. Для данного дня у меня есть дата, время засыпания этой ночью и время пробуждения на следующий день. Идея примерно как в этом xkcd комиксе . Мои попытки найти обратное уравнение восхода/заката, которое я нашел в Интернете, не увенчались успехом.
По сути, я хотел бы найти уравнение или алгоритм, чтобы дать приблизительное местоположение на Земле с определенным временем заката в определенный день и определенным временем восхода солнца на следующий день. Я не слишком беспокоюсь о точности, так как это просто для удовольствия, поэтому я надеюсь, что информация о высоте не нужна.
Я программист, поэтому моя цель - напечатать что-то вроде
>>>> locate(date = '2014-08-27', sunset = '10:00 PM', sunrise = '7:30 AM')
и вернуться
Latitude: 49.887, Longitude: 96.141
Я мог бы запрограммировать его сам, если бы достаточно разбирался в астрономии. Любая помощь приветствуется.
Чтобы избежать головной боли, связанной с поиском примерно двух десятков похожих решений в зигзагообразных границах часовых поясов, вы можете придерживаться UTC . Если вы хотите иметь дело с местным временем - это будет немного безумно, если вы также попытаетесь включить и выключить летнее время.
Точки на земле, где центр солнца совпадает с горизонтом ( игнорируя топографию, сплюснутость, атмосферную рефракцию, конечную скорость света и другие мелкие эффекты ), — это просто круг на земле, где конус, проведенный от Солнца, пересекает сферическая Земля.
вверху: сфера внутри конуса, с http://mathcentral.uregina.ca .
Но следующий шаг сложен — перейти от этого круга к координатам широты и долготы на поверхности, потому что ось наклонена, и потому что движение вокруг Солнца ускоряется и замедляется по мере того, как Земля приближается и удаляется от Солнца. Их можно аппроксимировать периодическими функциями с некоторыми коэффициентами, и это то, что вы найдете в математике за первым ответом. Для второго ответа я укажу два решения Python — PyEphem и Skyfield. Оба они просты в использовании, но вы отделены от фактической математики (в одном случае это эфемериды/таблица. Третий ответ — это действительно набор процедур НАСА/Лаборатории реактивного движения, которые высоко ценятся, но могут потребовать больше времени для вас, чтобы встать для скорости по сравнению с пакетами Python.
Это то, с чем вам придется немного покопаться, но если вам нравится программировать, это может быть именно то, что вы ищете. Веб - сайт Gaisma — один из моих любимых в Интернете — он прост в использовании и представляет множество информации в понятной графике. Нажмите вокруг!
Я считаю, что этот сайт использует алгоритмы из коллекции, найденной на этом сайте NOAA . Щелкните вокруг там также. Они предоставляют электронные таблицы Excel, содержащие алгоритмы и другие ресурсы. «Основной» ресурс — сборник алгоритмов, опубликованный в книге Astronomical Algorithms — Jean Meeus . На этой странице Amazon вы можете увидеть, что есть много книг с похожими названиями. Я бы порекомендовал пойти в библиотеку, если это возможно, потому что (на мой взгляд) всегда хорошо ходить в библиотеки. Однако некоторые из них можно найти в Интернете. Например, несколько страниц из книги « Астрономические формулы для калькуляторов» (1988 г.) содержат интересное оглавление.
Я скопирую немного текста из этого ответа :
Пакет Python PyEphem существует и хорошо поддерживается, и является pythonic-реинкарнацией XEphem . Я им не пользовался, но считаю, что он хранит достаточно информации об орбитальных параметрах в определенные эпохи для создания эфемерид, включая некоторые гравитационные возмущения. Другими словами, это гораздо больше, чем планеты, движущиеся по фиксированным эллиптическим орбитам вокруг неподвижного солнца. Поэтому я считаю, что он работает без подключения к Интернету.
Я никогда не использовал его, потому что мне рекомендовали посмотреть Skyfield , и это именно то, что мне было нужно. Он загружает стандартные эфемериды JPL, которые вы выбираете, а затем просто использует их с вашего жесткого диска. Однако, чтобы иметь дело с секундами координации и другими эффектами, связанными со временем , время от времени необходимо проверять Интернет на наличие обновлений информации о секундах координации, поскольку они произвольны.
Я не знаю, есть ли в Skyfield способ избежать этого. На самом деле это хороший вопрос. Если вы работаете со шкалой времени, в которой нет високосных секунд, я не уверен, будет ли она работать в текущей версии.
Пакеты Skyfield и PyEphem Python написаны и поддерживаются @BrandonRhodes.
Я включил простой скрипт Python только для того, чтобы проиллюстрировать, как можно использовать Skyfield. Если вам удобно кодировать без фигурных скобок, я настоятельно рекомендую вам попробовать. Это невероятно мощный и Pythonic.
Это только начало — вам нужно добавить некоторые улучшения для обнаружения восходов и закатов, и, возможно, в некоторых случаях более глобальный поиск. На самом деле, чтобы сделать эту работу надежной, необходимо немного утомительное ведение хозяйства.
примечание: вы можете включить атмосферное преломление, используя аргументы в apparent()
методе. Дополнительную информацию см. в документации Skyfield API , а для обсуждения итерации с использованием методов Skyfield — особенно решения для времен — см. этот полезный ответ .
def alt_lonlat(lon, lat, t):
topo = earth.topos(lat, lon)
alt, az, dist = topo.at(trise).observe(sun).apparent().altaz() ## apparent() args for atmospheric refraction
return alt.degrees
from skyfield.api import load
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as spo
data = load('de421.bsp')
ts = load.timescale()
# your example: '2014-08-27', sunset = '10:00 PM', sunrise = '7:30 AM'
trise = ts.utc(2014, 8, 27, 7, 30, 0)
tset = ts.utc(2014, 8, 27, 22, 0, 0)
earth = data['earth']
sun = data['sun']
zerozero = earth.topos(0.0, 0.0) # gotta start looking somewhere!
alt, az, dist = zerozero.at(trise).observe(sun).apparent().altaz() ## apparent() args for atmospheric refraction
print "at trise, JD = ", trise.tt
print "at (0N, 0E) Sun's altitude: ", alt.degrees, "azimuth: ", az.degrees
print "at (0N, 0E) Sun's distance (km): ", dist.km
# Find points on equator where sun is on horizon (rise or set) at t=trise
limits = ((0, 180.), (180, 360.))
lonzeros = []
for a, b in limits:
answer, info = spo.brentq(alt_lonlat, a, b,
args=(0.0, trise),
full_output = True )
if info.converged:
lonzeros.append(answer)
print "limits ", a, b, " converged! Found longitude (deg): ", answer
else:
print "limits ", a, b, "whaaaa?"
lonzeros.append(None)
# make some curves
lats = np.linspace(-60, 60, 13)
longis = []
for lon0 in lonzeros:
lons = []
for lat in lats:
answer, info = spo.brentq(alt_lonlat, lon0-90, lon0+90,
args=(lat, trise),
full_output = True )
if info.converged:
lons.append(answer)
else:
lons.append(None)
lons = [(lon+180)%360.-180 for lon in lons] # wraparound at +/- 180
longis.append(lons)
plt.figure()
for lons in longis:
plt.plot(lons, lats)
for lons in longis:
plt.plot(lons, lats, 'ok')
plt.xlim(-180, 180)
plt.ylim(-90, 90)
plt.title("at trise, JD = " + str(trise.tt))
plt.show()
Как указал @barrycarter в этом комментарии под этим ответом , ядра JPL SPICE доступны. Я не знаком с ними, но это то, что использует НАСА, так что это должно быть довольно хорошо :)
Вот несколько скриншотов для Лондона, Великобритания ( Gaisma отсюда ):
Answer 3: SPICE Kernels
раздела, сделайте это!skyfield
тег.Из-за сложности проблемы (см. мой комментарий выше) и того факта, что вам нужен только грубый ответ, почему бы не попробовать рассчитать время восхода/захода Солнца, скажем, с интервалом в один градус для всей Земли, а затем сравнить их со временем у тебя есть. Если одного градуса недостаточно, вы можете использовать меньший интервал, а также использовать диапазон в сравнении (скажем, +/- 5 минут).
Точное расстояние между вашими местоположениями и временным диапазоном будет зависеть от того, насколько точными вы хотите получить ответы, и оба они могут быть легко изменены, пока вы не будете удовлетворены результатами.
Этот подход может быть не самым эффективным, но при скорости современного компьютера это не займет много времени.
Как говорит @Andy, в любое время вокруг Земли есть большой круг, где Солнце в настоящее время находится на горизонте, либо восходит, либо садится (или и то, и другое в двух точках (муравьиной) Арктики). Этот большой круг можно описать координатами точки, в которой Солнце находится прямо над головой (это вектор, указывающий от центра Земли к этому месту на поверхности или к Солнцу).
Такой большой круг существует для вашего момента заката, а другой существует для вашего времени восхода солнца. Вас интересует одна из двух точек пересечения этих двух больших кругов.
Две большие окружности лежат в двух плоскостях, проходящих через центр Земли, и описываются двумя упомянутыми ранее векторами. Пересечение двух плоскостей представляет собой линию, проходящую через центр, направление которой является другим вектором (нормализованным векторным произведением двух векторов нормалей), который можно преобразовать обратно в два противоположных положения на поверхности Земли. Это решение было бы достаточно точным, если бы Земля была сферой.
Джеймс Скрич
Энди
ксанксерус
зефир
ооо
Latitude: 96.141, Longitude: 49.887
(широта больше 90°)ооо
пользователь21