Frage zur Optimierung eines Skripts

slart

Aktives Mitglied
Hallo,
eine an die bisherigen Fragen anschließende Frage ist folgende:

Dieses Skript berechnet den Schatten der Sonne in einer OSMap (mittels LeafLet, kann aber auch auf OpenLayer umprogrammiert werden).
In diesem Skript wird der Schatten-Layer (Vector Layer) autark berechnet. Das ist etwas ungünstig. Zudem wird die Longitude der Position der Sonne nicht berechnet, weshalb diese mittels diesem Skript nicht als Vector Circle in der Map angezeigt werden kann.

Die Funktion Sun() in diesem Skript berechnet die Position der Sonne. Seite 127 (120).

Die Frage ist: Welche Variable in der Funktion Sun() enthält den Wert der Variable gst im ersten Skript.
Zeile: var gst = GMST(julianDay);
Alternative Frage: Wie kann der Wert der Variable gst in der Funktion Sun() berechnet werden?

Die Lösung dieser Fragen würde das Terminator-Skript erleichtern, wenn der Wert für gst bereits in Sun() berechnet wird, weil Sun() zur Berechnung der Longitude sowieso benötigt wird (sowie von mir auch die Latitude daraus verwendet wird).

Meinen bisherigen Überprüfungen nach wird der Wert für gst nicht in Sun() berechnet. Aber eventuell könnte er dies. Doch dazu fehlen mir die Kenntnisse und Fähigkeiten. Deshalb frage ich hier.
 
Hallo slart,

deine Formulierungen sind etwas wirr, Verzeihung! Ich rate jetzt einmal und vermute dass gst die Greenwich Siderial Time ist.

Die mittlere Sternzeit in Greenwich musst du nicht zwangsläufig innerhalb von SUN() berechnen. Wenn du die julianische Tagzahl JD (aus der Weltzeit) bereits berechnet hast, kannst du die mittlere Sternzeit in Greenwich wie folgt berechnen:

Javascript:
// Winkel in Intervall [0°-360°] bringen
const range = x => (x % 360 + 360) % 360;


function getMeanSiderialTimeGW(jd) {
  let T, theta0;
  T = (jd - 2451545.0)/36525;
  theta0 = 280.46061837
           + 360.98564736629 * (jd - 2451545.0)
           + 0.000387933*T*T
           - (T*T*T)/38710000;
  return range(theta0);
}


// Mittlere Sternzeit Greenwich 3.10.2025, 00:00 UT
console.log(getMeanSiderialTimeGW(2460951.5));

// => 11.952595106326044 °
// => 0.7968396737550696 h => 0h 47m 48.6s

Die Funktion gibt dezimale Grad zurück, für dezimale Stunden musst du durch 15 teilen.


cs,
harald

--
 
Zuletzt bearbeitet:
Vielen Dank Harald, ich werde das gleich mal ausprobieren. Vorher aber noch Infos zum Topic, sowie eine an deinen Kommentar anschließende Info.

Das Terminator-Skript mit der Variable gst:
Javascript:
function julian(date) {
    /* Calculate the present UTC Julian Date. Function is valid after
     * the beginning of the UNIX epoch 1970-01-01 and ignores leap
     * seconds. */
    return (date / 86400000) + 2440587.5;
}

function GMST(julianDay) {
    /* Calculate Greenwich Mean Sidereal Time according to
         http://aa.usno.navy.mil/faq/docs/GAST.php */
    var d = julianDay - 2451545.0;
    // Low precision equation is good enough for our purposes.
    return (18.697374558 + 24.06570982441908 * d) % 24;

}

var gst = GMST(julianDay);
Direktlink zum Skript: Leaflet.Terminator/index.js at 8ed7de231cbaef3924564afeb23341083bada640 · joergdietrich/Leaflet.Terminator

Das Skript soll um diese beiden Funktionen gekürzt werden, indem der Wert der Variable gst bereits in der Funktion Sun() im Skript im PDF berechnet wird, in der bereits durch eine vorgenommene Erweiterung Longitude und Latitude berechnet werden.

Anhand deines Codes sehe ich, dass diese Berechnung bereits in der Funktion Aries() im PDF verwendet und der globalen Variable GHAAmean zugewiesen wird. Im PDF Seite 79 (72).
Javascript:
//GHA Aries
function Aries()
{
//Mean GHA Aries
var GHAAmean = norm_360_deg(280.46061837+360.98564736629*(JD-
2451545)+0.000387933*T2-T3/38710000);
//True GHA Aries
GHAAtrue = norm_360_deg(GHAAmean+delta_psi*cosd(eps));
}
norm_360_deg() entspricht deiner range().

Der Wert der Variablen T oder Tau sowie TE oder TD wird bereits im PDF in der function TimeMeasures() berechnet, ist also bereits vorhanden, als globale Variable.

Javascript:
// Calculating Julian date, century, and millennium
function TimeMeasures()
{
with(Math)
{
//Julian day (UT1)
if(month <= 2) {year -=1; month += 12;}
var A = floor(year/100);
var B = 2-A+floor(A/4);
JD0h = floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+B-1524.5;
JD = JD0h+dayfraction;
//Julian centuries since 2000 January 0.5
T = (JD-2451545)/36525;
T2 = T*T;
T3 = T*T2;
T4 = T*T3;
T5 = T*T4;
//Julian ephemeris day
JDE = JD+deltaT/86400;
//Julian centuries (TDT) from 2000 January 0.5
TE = (JDE-2451545)/36525;
TE2 = TE*TE;
TE3 = TE*TE2;
TE4 = TE*TE3;
TE5 = TE*TE4;
//Julian millenniums (TDT) from 2000 January 0.5
Tau = 0.1*TE;
Tau2 = Tau*Tau;
Tau3 = Tau*Tau2;
Tau4 = Tau*Tau3;
Tau5 = Tau*Tau4;
}
}

Auf die Schnelle: Könnte das stimmen?
Javascript:
// PDF === deins
GHAAmean === getMeanSiderialTimeGW(jd)

EDIT: Das stimmt:
Javascript:
// Terminator === PDF
gst === (GHAAmean / 15)

Die Variable GHAAmean hatte ich übersehen.
Besten Dank Harald!
 
Zuletzt bearbeitet:
Naja klar, dein GHAAmean scheint der Greenwich Hour Angle Aries zu sein, also der Stundenwinkel des mittleren Frühlingspunktes in Greenwich (Nullmeridian). Und warum GMST(julianDay) {...} UND GHAAmean = norm_360_deg(...)? Verstehe ich nicht.

Warum die Leute die das Script geschrieben haben das so komisch benennen weiß ich nicht. Aber kann ja jeder machen, wie er will, man sollte es nur nach ein paar Monaten noch interpretieren können, wenn man mal wieder am Algorithmus schraubt. Warum jetzt allerdings ein GHAAtrue berechnet werden muss, ist mir schleierhaft. Zwischen der mittleren und wahren Sternzeit ist der Unterschied im Bereich von ca. 1-2 Sekunden. Und wenn man eh schon ΔT nicht berücksichtigt, kann man die 2 Sekunden auch schmeißen. Den Unterschied kann man in der fertigen Grafik niemals sehen. Außerdem wird in der function GMST(julianDay) nur linear in T gerechnet.
Ich würde bei so einer Anwendung mit mittlerer Sternzeit und mittlerer Ekliptikschiefe auskommen, Nutation weg. Es sei denn, man will genauere Daten auch als Text an den Benutzer ausgeben.

cs,
harald

--
 
Hallo Harald,
habe im Kommentar === als Vergleichsoberatoren verwendet, also ob das eine dem anderen gleich ist.

die unterschiedliche Benennung der Variablen in verschiedenstens Skripten ist mir auch schon aufgefallen und ohne einen Kommentar dazu ist es für Laien wie mich sehr schwer bis unmöglich zu verstehen. Da helfen dann meistens nur noch die festen Zahlenwerte und Formeln zur Wiedererkennung.

Bei sowas wie GHAAtrue geht es meinen Beobachtungen nach eher weniger um die Genauigkeit zu einem bestimmten Zeitpunkt, da jede Berechnung immer nur eine Annäherung ist, sondern um die Berechnung der Schwankungen innerhalb einer Zeitspanne bei einer möglichst genauen Berechnung. Dabei ist nicht der Unterschied bei den Schwankungen, also zwischen Maximum und Minimum, sondern die Veränderung der Schwankung an sich relevant. Bin da nicht so gut darin das zu erklären. Bei den Funktionen im PDF geht es nicht um eine simple Visualisierung. Sicher könnten die Funktionen für eine simple Visualisierung um ein vielfaches vereinfacht werden. Aber wer machts? ;) Für die heutigen Prozessoren sind die Berechnungen ein Klax. Es spielt dabei also keine Rolle Strom und Rechnerkapazitäten im Nanobereich einzusparen. Thema Benchmark. Perfektion ist anders. Aber es genügt.
 
Bei sowas wie GHAAtrue geht es meinen Beobachtungen nach eher weniger um die Genauigkeit zu einem bestimmten Zeitpunkt, da jede Berechnung immer nur eine Annäherung ist, sondern um die Berechnung der Schwankungen innerhalb einer Zeitspanne bei einer möglichst genauen Berechnung.
Hm? Es tut mir leid, aber im spanischen PDF auf S. 73 steht Folgendes:

Javascript:
//
GHA Aries
function Aries()
{
//Mean GHA Aries
var GHAAmean = norm_360_deg(280.46061837+360.98564736629*(JD-2451545)+0.000387933*T2-T3/38710000);
//True GHA Aries
GHAAtrue = norm_360_deg(GHAAmean+delta_psi*cosd(eps));
}

GHAAmean ist die mittlere Sternzeit in Greenwich (London), genau so wie in meinem obigen Schnippsel. Dann wird GHAAtrue berechnet, d.h. um die Nutation korrigiert mit +delta_psi*cosd(eps). Und das ist dann die wahre Sternzeit für Greenwich. Wie schon gesagt, für deine Zwecke ist das irrelevant. Der Winkel epsilon (eps) ist dabei selbst die wahre Ekliptikschiefe - also korrigiert - nicht die mittlere Ekliptikschiefe.

Ich verstehe nicht, warum du aus den verschiedensten Quellen Code zusammenwürfelst, da wird man ja schwuppi. Natürlich werden in unterschiedlichen Quellen Funktionen und Variablen anders benannt. Und, du hast noch immer nicht klar dargelegt, was genau du eigentlich darstellen möchtest? Ist das irgendwie ein Geheimprojekt oder so?

Soweit ich das bis dato verstanden habe, nutzt du eine Landkarte von OSM (über HTML canvas), über die du die Tag-Nacht-Grenze legst (Terminator), und in der angezeigt werden soll, wo gerade die Sonne bzw. der Mond steht. Und je nach Zeit-/Ortseingabe soll sich das eben dynamisch verändern. Dafür braucht es keine hochgenauen Koordinaten für Sonne und Mond.

Es spielt dabei also keine Rolle Strom und Rechnerkapazitäten im Nanobereich einzusparen.
Einspruch, euer Ehren! Meine Herangehensweise folgt hier dem Prinzip "so einfach wie möglich, aber nicht einfacher". Auch wenn die Einsparungen nicht weltbewegend sein mögen, warum sollte man das Ganze komplizierter machen als notwendig?

cs,
harald

--
 
warum sollte man das Ganze komplizierter machen als notwendig?
weil ... und das wäre vermutlich das "geheime" daran ... man nicht viel Ahnung davon hat (und auch nicht die Zeit).
Es geht nicht nur um die Visualisierung in einer Map, sondern auch um die Anzeige von Werten. Von daher schadet es nicht, wenn diese sehr genau sind. Allerdings stimme ich dir zu, dass eine grobe Berechnung genügen würde. Hab ich nur nicht gefunden und zum selbermachen reicht es nicht.

Du warst mir bisher eine große Hilfe, auch wenn letztendlich vieles durch mich selbst gelöst wurde. Deine Hinweise haben dazu beigetragen.
 
weil ... und das wäre vermutlich das "geheime" daran ... man nicht viel Ahnung davon hat (und auch nicht die Zeit).
Ähm, gerade das wären ja 2 Gründe, es nicht komplizierter zu machen als notwendig....

Es geht nicht nur um die Visualisierung in einer Map, sondern auch um die Anzeige von Werten.
OK, also doch anzeigen. Es gibt mittlerweile zuhauf Repositorys, wo man alles aus einer Hand übersichtlich zur Verfügung hat, z.B. MeeusJS oder PyMeeus. Für die allermeisten Anwendungen sind die Daten genau genug. Die Anwendung ist hinreichend dokumentiert, da kommst du schon hin.

Du warst mir bisher eine große Hilfe, auch wenn letztendlich vieles durch mich selbst gelöst wurde. Deine Hinweise haben dazu beigetragen.
Alles klar! :cool::coffee:

cs,
harald

--
 
Es wird benötigt (mindestens)
- Astro.js (68 Zeilen)
- Paralax.js (87 Zeilen)
- Nutation (205 Zeilen)
- Moon.js (458 Zeilen)
macht: 818 Zeilen
- und eventuell noch einiges mehr.
Ich bin jetzt bei rund 350 Zeilen (betreffenden Code).
Aber egal, habe nicht vor hieraus einen Wettbewerb zu machen. ;)
Und ja, insgesamt sind auch 244 kb nicht viel für die Berechnung so vieler Werte.
 
Das besagte Repo ist deswegen recht klein, weil es die Planeten nicht beinhaltet, soweit ich gesehen habe. Diese werden aber für deine Zwecke auch nicht benötigt. Wenn man die 4 genannten Dateien minifiziert, hat man 4 Zeilen, Spaß beiseite :cool:

Natürlich geht es hier nicht um einen Wettbewerb. Und natürlich muss man sich ein wenig in die Nomenklatur einarbeiten (das macht jeder anders), was was bedeuteut bzw. ausrechnet. Aber man hat alles Wichtige strukturiert aus einer Quelle und es ist nicht von Extra-Packages abhängig, läuft autark vom eigenen Server. Ich selbst bin nicht so der Freund dieser "Alles-und-Jedes-in-Objekte-packen-Philosophie", ich verwende lieber Functions, aber das darf ja jeder halten wie er will.

cs,
harald

--
 
Es könnten auch Classes verwendet werden, was den Functions in Objects in etwa gleich kommt. Das hat schon Sinn. Es vermeidet Fehler durch doppelte Funktionennamen, was bei größeren Repos passieren kann, oder wenn anderes mit eingebunden werden darf und soll. Hab das bisher aber auch nur einmal angewandt.

Das Repo ist schon easy. Alles in einem. Hätte ich das vorher gekannt ... würde ichs verwenden.
 
Es könnten auch Classes verwendet werden, was den Functions in Objects in etwa gleich kommt.
Hm. Also Klassen braucht es hier eigentlich nicht, du willst ja nicht mehrere/viele Instanzen ein und desselben "Objekts" verwenden, oder? Wäre also in diesem Fall mMn zuviel des Guten. Bei großen Projekten, ja.

Das Repo ist schon easy. Alles in einem. Hätte ich das vorher gekannt ... würde ichs verwenden.
Na du bist gut :ROFLMAO:, das ist 1000mal einfacher als zusammengesuchter Code, allein die Wartung...._affeaugen:

cs,
harald

--
 
Vermutlich ... hat mich etwas überzeugt, da mir eine neue Idee kam, die mit integriert werden will, ... Aus diesem Grund suche ich wieder das Äquivalent zur Variable gst in diesem MeeusJS Repository. Weißt du auf Anhieb welche Variable den Wert enthält? Habe nichts gefunden. Es müsste ja etwas mit dem Wert 280.46061837 sein, oder? Dann müsste das Repository um eine Funktion Aries() erweitert werden.

Wobei, ... das Repo MeeusJS enthält wohl Fehler und wird nicht mehr gepflegt. Stand: 5 unbeantwortete Issues von 2023. Letzter Commit: 2022.
 
Zuletzt bearbeitet:
In der Datei → lib/Astro.Sidereal.js ist die Sternzeit drinnen (chapter 12). Es muss nicht zwangsläufig der Wert 280.46061837 dort auftreten.

Javascript:
let jd0 = new A.JulianDay(new Date());
console.log(jd0.jd);
    
let gmst = A.Sidereal.mean(jd0);
let gmstApp = A.Sidereal.apparent(jd0);
console.log(gmst/3600);
console.log(gmstApp/3600);
console.log((gmst-gmstApp));

Zuerst JD aus dem Datum ausrechnen und dann die mittlere oder wahre Sternzeit in Greewich. Diese wird in Sekunden ausgegeben, deswegen die Division durch 3600, dann hast du Dezimalstunden. Der letzte log gibt die Differenz der mittleren von der wahren Sternzeit in Sekunden aus.

cs,
harald

--
 
Danke, aber was ist denn nun das Äquivalent zu gst? Du schriebst "vermute dass gst die Greenwich Siderial Time ist."

Der Wert der Variable GHAAmean ist der Wert der Variable gst. Du schriebst, GHAA ist "Greenwich Hour Angle Aries".

Da haben wir jetzt schon zwei Begriffe für ein und dasselbe:
- Greenwich Siderial Time
- Greenwich Hour Angle Aries

Und nun schreibst du etwas über "mittlere oder wahre Sternzeit in Greewich" und die Variable gmst sowie gmstApp. "Sideral" bedeutet Sternzeit. "Wahre" ist vermutlich "apparent". Ist gst "mittlere Sternzeit" und folglich gst = gmst, oder ist gst "wahre Sternzeit" und folglich gst = gmstApp?
 
Tja, Herr Kollege, mit den Begrifflichkeiten sollte man sich vorher vertraut machen, nix für ungut. Und warum wundert dich das? Viele Quellen, viele Bezeichnungen, so ist das dann halt. Man sollte eben mit einem konsistenden System arbeiten. Mir liegen diese Objekt-Orgien wie gesagt nicht so. Aber du hast eh alles richtig aufgezählt!

• Sternzeit = Stundenwinkel des Frühlingspunktes. Sternzeit gibt an, wie weit westlich der Frühlingspunkt vom lokalen Meridian steht. Und wenn der Meridian jener von Greenwich ist, dass ist das eben die gst, GMST, gmst,... kannst es nennen wie du möchtest. Wenn der Meridian an deinem lokalen Ort gemeint ist, hast du die LMST (Local Mean Siderial Time), kannst es nennen wie du möchtest. Schau mal hier.

• Aries = Widder => Widderpunkt, früher ein Ausdruck für den Frühlingspunkt, weil er in diesem Sternbild lag. Heute liegt er im Sternbild Fische.

• Sidereal = "auf die Sterne bezogen"

Mean siderial time = mittlere Sternzeit

• apparent = "ersichtlich, scheinbar, offenbar", in der Astronomie aber die "wahre....(Sternzeit). Die um die Nutation korrigierte mittlere Sternzeit.

cs,
harald

--
 
Vielen Dank. Die Ausdrücke "gemittelte" (mittlere, mean) und "wahre" (true) sind mir bereits geläufig. Meine Frage ist und war, ob die Variable gst einen mean oder einen true Wert hat? Also ob ...

if( (gst === gmst) === true)
oder
if ((gst === gmstApp) === true)

Background: Das MeeusJS Repo berechnet equatorial Coordinates. Pluspunkt. Das Shadow-Layer Skript berechnet alles autonom. Damit nichts doppelt berechnet werden muss, kann die Longitude vom MeeusJS an das Shadow-Layer übergeben werden. Damit im Shadow-Layer JD nicht neu berechnet werden muss, könnte auch das von MeeusJS an Shadow übergeben werden, aber es könnte vom MeeusJS auch gleich der Wert für gst im Shadow übergeben werden, wenn gewusst wird welcher dieser im MeeusJS ist.

Also ist die erste Frage, ob gst im Shadow mean oder true ist, und danach die Frage, was die äquivalente Variable von gst im MeeusJS ist, damit diese an das Shadow übergeben werden kann. Bisher weiß ich nur, dass gst = Greenwich Sideral Time ist, aber nicht ob mean oder true.

Mittels der Funktion Aries() konnte bereist herausgefunden werden, dass GHAAmean = mean, sowie gst = GHAAmean, also gst = mean ist.

Im MeeusJS ist es exemplarischer:
A.Sidereal.mean(jd0) = mean (mittlere)
A.Sidereal.apparent(jd0) = true (wahr)

Also ist aller Wahrscheinlichkeit nach
gst = A.Sidereal.mean(jd0)

PS: Ich könnte es einfach testen, aber dafür hab ich derzeit keine Kapazitäten.
 
Ich weiß ja nicht, was gst in deinem Script für einen Parameter hat, ich nehme an die Julianische Tagzahl JD?
Wirf doch einfach mal in beide Funktionen diesselbe JD und schau was herauskommt, das dauert nicht mal eine Minute. A.Sidereal.mean(jd0) berechnet jedenfalls die mittlere Sternzeit in Greenwich, aber in Sekunden.

Also ist aller Wahrscheinlichkeit nach
gst = A.Sidereal.mean(jd0)
Sieht so aus, ja.
Für Stunden => /3600
Für Grad => /3600 dann *15 oder gleich /240

PS: Ich könnte es einfach testen, aber dafür hab ich derzeit keine Kapazitäten.
Hm, soll ich das jetzt für dich machen? Der Test dauert sicher nicht so lange wie dein Posting zu schreiben.

cs,
harald

--
 
Ich weiß ja nicht, was gst in deinem Script für einen Parameter hat, ich nehme an die Julianische Tagzahl JD?
Das hatte ich doch bereits Eingangs verlinkt, direkt zur Codzeile:
Und da steht es ja eigentlich auch:
gst wird mit der Funktion GMST() berechnet, und bei der steht: "Calculate Greenwich Mean Sidereal Time"
Ansonsten ja, testen muss ich das sowieso selbst noch.
Dann sieht es gut aus auf das MeeusJS umzusteigen, bzw. dieses mal anzutesten.
 
In dem von dir angegebenen Link steht in Zeile 12

Javascript:
function GMST(julianDay) {
    /* Calculate Greenwich Mean Sidereal Time according to
         http://aa.usno.navy.mil/faq/docs/GAST.php */
    var d = julianDay - 2451545.0;
    // Low precision equation is good enough for our purposes.
    return (18.697374558 + 24.06570982441908 * d) % 24;
}

Allerdings "low precision is good enough". Und da steht auch dein konstanter Term 280.46061837°, denn 18.697374558 h · 15 °/h = 280.46061837°.
Das ist die (mittlere) Sternzeit in Greenwich am 1.1.2000, 12:00 UT.

cs,
harald

--
 
Zurück
Oben