Ich arbeite zum Spaß an einem Projekt, bei dem ich einige Schlafdaten geografisch darstelle. Für einen bestimmten Tag habe ich ein Datum, eine Zeit zum Einschlafen an diesem Abend und eine Zeit zum Aufwachen am nächsten Tag. Die Idee ist so etwas wie dieser xkcd-Comic . Meine Versuche, die Umkehrung der Sonnenaufgangs-/Sonnenuntergangsgleichungen zu nehmen, die ich online gefunden habe, waren nicht erfolgreich.
Grundsätzlich möchte ich eine Gleichung oder einen Algorithmus finden, um einen ungefähren Ort auf der Erde mit einer bestimmten Sonnenuntergangszeit an einem bestimmten Tag und einer bestimmten Sonnenaufgangszeit am nächsten Tag anzugeben. Ich bin nicht allzu besorgt über die Genauigkeit, da dies nur zum Spaß ist, also hoffe ich, dass Höheninformationen nicht notwendig sind.
Ich bin Programmierer, also ist das Ziel wirklich, so etwas wie tippen zu können
>>>> locate(date = '2014-08-27', sunset = '10:00 PM', sunrise = '7:30 AM')
und zurückkommen
Latitude: 49.887, Longitude: 96.141
Ich könnte es selbst programmieren, wenn ich nur genug von Astronomie verstünde. Jede Hilfe wird sehr geschätzt.
Um die Kopfschmerzen zu vermeiden, die mit der Suche nach ungefähr zwei Dutzend ähnlicher Lösungen in den Zick-Zack-Zeitzonengrenzen verbunden sind, sollten Sie vielleicht bei UTC bleiben . Wenn Sie sich mit der Ortszeit befassen möchten, wird es ein wenig verrückt, wenn Sie auch versuchen, die Sommerzeit ein- und auszuschalten.
Die Punkte auf der Erde, wo der Mittelpunkt der Sonne mit dem Horizont zusammenfällt ( ohne Topographie, Abflachung, atmosphärische Brechung, die endliche Lichtgeschwindigkeit und andere kleine Effekte ) ist genau der Kreis auf der Erde, wo ein von der Sonne gezeichneter Kegel einen schneidet sphärische Erde.
oben: Eine Kugel in einem Kegel, von http://mathcentral.uregina.ca .
Aber der nächste Schritt ist schwierig – von diesem Kreis zu den Lat/Lon-Koordinaten auf der Oberfläche zu gelangen, weil die Achse geneigt ist und weil die Bewegung um die Sonne schneller und langsamer wird, wenn sich die Erde näher und weiter von der Sonne entfernt. Diese können durch periodische Funktionen mit einigen Koeffizienten angenähert werden, und das finden Sie in der Mathematik hinter der ersten Antwort. Für die zweite Antwort werde ich zwei Python-Lösungen auflisten - PyEphem und Skyfield. Beide sind einfach zu bedienen, aber Sie sind von der eigentlichen Mathematik getrennt (in einem Fall handelt es sich um eine Ephemeride / Tabelle. Die dritte Antwort ist wirklich eine Sammlung von NASA / JPL-Routinen, die hoch angesehen sind, aber möglicherweise mehr Zeit für Sie benötigen, um aufzustehen im Vergleich zu den Python-Paketen zu beschleunigen.
Dies ist etwas, in das Sie sich ein wenig einarbeiten müssen, aber wenn Sie gerne programmieren, ist es möglicherweise genau das, wonach Sie suchen. Die Gaisma -Website ist einer meiner Favoriten im Internet - einfach zu bedienen und präsentiert eine Menge Informationen in leicht verständlichen Grafiken. Klicken Sie sich um!
Ich glaube , dass diese Seite Algorithmen aus der Sammlung verwendet , die auf dieser NOAA - Seite zu finden ist . Klicken Sie sich auch dort um. Sie stellen Excel-Tabellen zur Verfügung, die die Algorithmen und andere Ressourcen enthalten. Die "Haupt"-Ressource ist eine Sammlung von Algorithmen, die im Buch Astronomical Algorithms - Jean Meeus veröffentlicht wurden . Auf dieser Amazon-Seite können Sie sehen, dass es viele ähnlich betitelte Bücher gibt. Ich würde empfehlen, wenn möglich in eine Bibliothek zu gehen, weil es (meiner Meinung nach) immer gut ist, in Bibliotheken zu gehen. Teile davon sind jedoch online zu finden. Beispielsweise enthalten einige Seiten aus dem Buch Astronomical Formulas for Calculators (1988) ein interessantes Inhaltsverzeichnis.
Ich kopiere einen Teil des Textes aus dieser Antwort :
Das Python-Paket PyEphem wurde herumgereicht und gut unterstützt und ist die pythonische Reinkarnation von XEphem . Ich habe es nicht verwendet, aber ich glaube, es enthält genügend Informationen über Orbitalparameter in bestimmten Epochen, um eine Ephemeride zu erzeugen, einschließlich einiger Gravitationsstörungen. Mit anderen Worten, es ist viel mehr als Planeten, die sich auf festen elliptischen Bahnen um eine feste Sonne bewegen. Also ich glaube es läuft ohne Internetverbindung.
Ich habe es nie benutzt, weil mir empfohlen wurde, mir Skyfield anzusehen, und es ist genau das, was ich brauchte. Es lädt eine Standard-JPL-Ephemeride herunter, die Sie auswählen, und verwendet sie danach einfach von Ihrer Festplatte. Um jedoch mit Schaltsekunden und anderen zeitbezogenen Effekten fertig zu werden, muss es gelegentlich im Internet nach Aktualisierungen von Schaltsekundeninformationen suchen, da diese willkürlich sind.
Ich weiß nicht, ob Skyfield einen Modus hat, um das zu vermeiden. Eigentlich ist das eine gute Frage. Wenn Sie mit einer Zeitskala arbeiten, die keine Schaltsekunden hat, bin ich mir nicht sicher, ob sie in ihrer aktuellen Version ausgeführt wird.
Sowohl Skyfield- als auch PyEphem-Python-Pakete wurden geschrieben und werden von @BrandonRhodes gepflegt.
Ich habe ein einfaches Python-Skript beigefügt, um zu veranschaulichen, wie Skyfield verwendet werden kann. Wenn Sie mit dem Codieren ohne geschweifte Klammern vertraut sind, würde ich Ihnen dringend empfehlen, dies auszuprobieren. Es ist unglaublich mächtig und pythonisch.
Dies ist nur ein Anfang - Sie müssen etwas bessere Haushaltsführung hinzufügen, um Sonnenaufgänge und Sonnenuntergänge zu erkennen, und in einigen Fällen möglicherweise eine globalere Suche. Tatsächlich ist etwas mühsame Haushaltsführung erforderlich, um diese Arbeit robust zu machen.
Hinweis: Sie können die atmosphärische Refraktion mit den Argumenten in der apparent()
Methode aktivieren. Weitere Informationen finden Sie in der Skyfield-API- Dokumentation, und für eine Diskussion über das Iterieren mit Skyfield-Methoden – insbesondere das Lösen von Zeiten – siehe diese hilfreiche Antwort .
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()
Wie von @barrycarter in diesem Kommentar unter dieser Antwort hervorgehoben , sind die JPL SPICE-Kernel verfügbar. Ich bin mit ihnen nicht vertraut, aber es ist das, was die NASA verwendet, also muss es ziemlich gut sein :)
Hier sind einige Screenshots für London, UK ( Gaisma von hier ):
Answer 3: SPICE Kernels
Abschnitts verbessern können, tun Sie dies bitte!skyfield
Wenn Sie Python-Fragen haben, können Sie diese auf Stackoverflow stellen – vergessen Sie nicht, das Tag
hinzuzufügen .Aufgrund der Komplexität des Problems (siehe meinen Kommentar oben) und der Tatsache, dass Sie nur eine grobe Antwort wünschen, warum versuchen Sie nicht, die Zeiten des Sonnenaufgangs / -untergangs in Intervallen von beispielsweise einem Grad für die gesamte Erde zu berechnen und diese dann mit den Zeiten zu vergleichen Sie haben. Wenn ein Grad nicht nahe genug ist, können Sie ein kleineres Intervall verwenden und auch einen Bereich für den Vergleich verwenden (z. B. +/- 5 Minuten).
Wie genau Ihr Standortabstand und Zeitbereich genau ist, hängt davon ab, wie genau Sie Ihre Antworten wünschen, und beide können leicht angepasst werden, bis Sie mit den Ergebnissen zufrieden sind.
Dieser Ansatz ist vielleicht nicht der effizienteste, sollte aber bei der Geschwindigkeit moderner Computer nicht sehr lange dauern.
Wie @Andy sagt, gibt es zu jeder Zeit einen großen Kreis um die Erde, in dem sich die Sonne derzeit am Horizont befindet und entweder aufgeht oder untergeht (oder beides an zwei Punkten in der (Ant-) Arktis). Dieser Großkreis kann durch die Koordinaten des Punktes beschrieben werden, an dem die Sonne direkt über ihm steht (das ist der Vektor, der vom Erdmittelpunkt zu diesem Ort auf der Oberfläche oder zur Sonne zeigt).
Solch ein großer Kreis existiert für deinen Moment des Sonnenuntergangs und ein anderer existiert für deine Zeit des Sonnenaufgangs. Sie interessieren sich für einen der beiden Schnittpunkte dieser beiden Großkreise.
Die beiden Großkreise liegen in zwei Ebenen durch den Erdmittelpunkt, beschrieben durch zwei der zuvor erwähnten Vektoren. Der Schnittpunkt der beiden Ebenen ist eine Linie durch das Zentrum, dessen Richtung ein weiterer Vektor (das normalisierte Kreuzprodukt der beiden Normalenvektoren) ist, der in zwei Antipodenpositionen auf der Erdoberfläche zurückgerechnet werden kann. Diese Lösung wäre ziemlich genau, wenn die Erde eine Kugel wäre.
James Schrei
Andy
xanxerus
Zephyr
äh
Latitude: 96.141, Longitude: 49.887
(Breitengrad größer als 90°)äh
Benutzer21