Die Himmelstafel von Tal-Qadi/ EkliptikaleKoordinatenMondSonne

/*
  Source file: Mondkoordinaten.java
  Program: Bestimmung der ekliptikalen Koordinaten von Sonne und Mond
  Author: Markus Bautsch
  Licence: public domain
  Date: 23 Juni 2020
  Version: 1.0
  Programming language: Java
 */

// Diese Klasse dient zur Berechnung der ekliptikalen Koordinaten von Sonne und Mond
// für den Zeitpunkt t eines Julianischen Datums in Julianischen Jahrhunderten der Standardepoche J2000.
// Aus den ekliptikalen Längen von Mond und Sonne können Mondphase und Mondalter abgeleitet werden.
// Unter Verwendung der Formeln aus: Oliver Montenbruck, Thomas Pfleger: ''Astronomie mit dem Personal Computer'',
// Springer-Verlag Berlin Heidelberg GmbH, 1989, ISBN 978-3-662-05865-7

public class EkliptikaleKoordinatenMondSonne
{
	// Allgemeine Konstanten
	private final static double pi2 = 2 * java.lang.Math.PI; // voller Kreis im Bogenmaß
	private final static double kreisInBogengrad = 360; // voller Kreis in Bogengrad
	private final static double kreisInBogensekunden = kreisInBogengrad * 60 * 60; // voller Kreis in in Bogensekunden
	private final static double radProGrad = pi2 / kreisInBogengrad; // Umrechnungsfaktor von Bogengrad nach Bogenmaß
	private final static double arc = kreisInBogensekunden / pi2; // Umrechnungsfaktor von Bogenmaß nach Bogensekunden

	// Die Methode "fractionPart" berechnet die dezimalen Nachkommastellen des Parameters "zahl"
	public static double fractionPart (double zahl)
	{
		double fractionPart = zahl - java.lang.Math.floor (zahl);
		return fractionPart;
	}

	// Die Methode "mittlereAnomalieSonne" berechnet die mittlere Anomalie der Sonne zum Zeitpunkt "t".
	public static double mittlereAnomalieSonne (double t) 
	{
		double mittlereAnomalieSonne = pi2 * fractionPart (0.99312619 + 99.99735956 * t - 0.00000044 * t * t);
		return mittlereAnomalieSonne;
	}

	// Die Methode "mittlereAnomalieMond" berechnet die mittlere Anomalie des Mondes zum Zeitpunkt "t".
	public static double mittlereAnomalieMond (double t) 
	{
		double anomalieMond = pi2 * fractionPart (0.37489701 + 1325.55240982 * t + 0.00002565 * t * t);
		return anomalieMond;
	}

	// Die Methode "mittlereElongationMond" berechnet die mittlere Elongation des Mondes,
	// also die Differenz der mittleren Längen von Sonne und Mond, zum Zeitpunkt "t".
	public static double mittlereElongationMond (double t) 
	{
		double mittlereElongationMond = pi2 * fractionPart (0.82736186 + 1236.85308708 * t - 0.00000397 * t * t);
		return mittlereElongationMond;
	}

	// Die Methode "mittlererAbstandMondAufsteigenderKnoten" berechnet den mittleren Abstand des Mondes
	// vom aufsteigenden Knoten zum Zeitpunkt "t".
	public static double mittlererAbstandMondAufsteigenderKnoten (double t)
	{
		double mittlererAbstandMondAufsteigenderKnoten = pi2 * fractionPart (0.25909118 + 1342.22782980 * t - 0.00000892 * t * t);
		return mittlererAbstandMondAufsteigenderKnoten;
	}

	// Die Methode "korrekturLaengeMond" berechnet die Korrektur für die ekliptikale Länge des Mondes zum Zeitpunkt "t".
	public static double korrekturLaengeMond (double t) 
	{
		double mittlereAnomalieSonne = mittlereAnomalieSonne (t);
		double mittlereAnomalieMond = mittlereAnomalieMond (t);
		double mittlereElongationMond = mittlereElongationMond (t);
		double mittlererAbstandMondAufsteigenderKnoten = mittlererAbstandMondAufsteigenderKnoten (t);
		double korrekturLaengeMond =
			22640 * java.lang.Math.sin (mittlereAnomalieMond)
			-4586 * java.lang.Math.sin (mittlereAnomalieMond - 2 * mittlereElongationMond)
			+2370 * java.lang.Math.sin (2 * mittlereElongationMond)
			 +769 * java.lang.Math.sin (2 * mittlereAnomalieMond)
			 -668 * java.lang.Math.sin (mittlereAnomalieSonne)
			 -412 * java.lang.Math.sin (2 * mittlererAbstandMondAufsteigenderKnoten)
			 -212 * java.lang.Math.sin (2 * mittlereAnomalieMond - 2 * mittlereElongationMond)
			 -206 * java.lang.Math.sin (mittlereAnomalieMond + mittlereAnomalieSonne - 2 * mittlereElongationMond)
			 +192 * java.lang.Math.sin (mittlereAnomalieMond + 2 * mittlereElongationMond)
			 -165 * java.lang.Math.sin (mittlereAnomalieSonne - 2 * mittlereElongationMond)
			 +148 * java.lang.Math.sin (mittlereAnomalieMond - mittlereAnomalieSonne)
			 -125 * java.lang.Math.sin (mittlereElongationMond)
			 -110 * java.lang.Math.sin (mittlereAnomalieMond + mittlereAnomalieSonne)
			  -55 * java.lang.Math.sin (2 * mittlererAbstandMondAufsteigenderKnoten - 2 * mittlereElongationMond);
		return korrekturLaengeMond;
	}

	// Die Methode "ekliptikaleLaengeMond" berechnet die ekliptikale Länge des Mondes zum Zeitpunkt "t".
	public static double ekliptikaleLaengeMond (double t) 
	{
		double mittlereLaengeMond = fractionPart (0.60643382 + 1336.85522467 * t - 0.00000313 * t * t); // im Bogenmaß
		double differenzLaengeMond = korrekturLaengeMond (t) / kreisInBogensekunden;
		double ekliptikaleLaengeMond = pi2 * fractionPart (mittlereLaengeMond + differenzLaengeMond) / radProGrad;
		return ekliptikaleLaengeMond;
	}

	// Die Methode "ekliptikaleBreiteMond" berechnet die ekliptikale Breite des Mondes zum Zeitpunkt "t".
	public static double ekliptikaleBreiteMond (double t) 
	{
		double mittlereAnomalieSonne = mittlereAnomalieSonne (t);
		double mittlereAnomalieMond = mittlereAnomalieMond (t);
		double mittlereElongationMond = mittlereElongationMond (t);
		double mittlererAbstandMondAufsteigenderKnoten = mittlererAbstandMondAufsteigenderKnoten (t);
		double differenzLaengeMond = korrekturLaengeMond (t);

		// Korrekturelement S
		double s =
			mittlererAbstandMondAufsteigenderKnoten +
			(
				differenzLaengeMond + 412 * java.lang.Math.sin (2 * mittlererAbstandMondAufsteigenderKnoten)
				+ 541 * java.lang.Math.sin (mittlereAnomalieSonne)
			) / arc;

		// Korrekturelement H
		double h = mittlererAbstandMondAufsteigenderKnoten - 2 * mittlereElongationMond;

		// Korrekturelement N
		double n =
			-526 * java.lang.Math.sin (h)
			 +44 * java.lang.Math.sin (mittlereAnomalieMond + h)
			 -31 * java.lang.Math.sin (-mittlereAnomalieMond + h)
			 -23 * java.lang.Math.sin (mittlereAnomalieSonne + h)
			 +11 * java.lang.Math.sin (-mittlereAnomalieSonne + h)
			 -25 * java.lang.Math.sin (-2 * mittlereAnomalieMond + mittlererAbstandMondAufsteigenderKnoten)
			 +21 * java.lang.Math.sin (-mittlereAnomalieMond + mittlererAbstandMondAufsteigenderKnoten);

		double ekliptikaleBreiteMond = (18520 * java.lang.Math.sin (s) + n) / arc / radProGrad;
		return ekliptikaleBreiteMond;
	}

	// Die Methode "ekliptikaleLaengeSonne" berechnet die ekliptikale Länge der Sonne zum Zeitpunkt "t".
	public static double ekliptikaleLaengeSonne (double t) 
	{
		double anomalieSonne = mittlereAnomalieSonne (t);
		double differenzLaengeSonne =
			6893 * java.lang.Math.sin (anomalieSonne)
			+ 72 * java.lang.Math.sin (2 * anomalieSonne);
		double laenge =
			0.7859453
			+ anomalieSonne / pi2
			+ (6191.2 * t + differenzLaengeSonne) / kreisInBogensekunden;
		double ekliptikaleLaengeSonne = 
			pi2 * fractionPart (laenge) / radProGrad;
		return ekliptikaleLaengeSonne;
	}

	// Die Methode "mondphase" berechnet die Phase des Mondes zum Zeitpunkt "t" in Prozent.
	public static double mondphase (double t)
	{
		double elongation = ekliptikaleLaengeMond (t) - ekliptikaleLaengeSonne (t);
		double sinElongation = java.lang.Math.sin (elongation * radProGrad / 2);
		double mondphase = 100 * sinElongation * sinElongation;
		return mondphase;
	}

	// Die Methode "mondphase" berechnet das Alter des Mondes zum Zeitpunkt "t" in Bogengrad.
	public static double mondalter (double t)
	{
		double mondalter = ekliptikaleLaengeMond (t) - ekliptikaleLaengeSonne (t);
		while (mondalter < 0)
		{
			mondalter = mondalter + kreisInBogengrad;
		}
		return mondalter;
	}

	// Die Methode "t" berechnet das Datum des Julianischen Datums in Bezug zur Standardepoche J2000.
	public static double t (double julianischesDatum)
	{
		final double bezugsdatum = 2451545;
		final double julianischesJahrhundert = 36525;
		double t = (julianischesDatum - bezugsdatum) / julianischesJahrhundert;
		return t;
	}

	// main-Methode für Aufruf des Programms
	public static void main (java.lang.String [] arguments)
	{
		double julianischesDatum = 2458992.237; // 22. Mai 2020, 19:41:17 h:m:s MESZ
		double t = t (julianischesDatum);
		java.lang.System.out.println ("Julianisches Datum = " + julianischesDatum);
		java.lang.System.out.println ("Ekliptikale Länge  der Sonne  = " + ekliptikaleLaengeSonne (t) + "°");
		java.lang.System.out.println ("Ekliptikale Länge  des Mondes = " + ekliptikaleLaengeMond (t) + "°");
		java.lang.System.out.println ("Ekliptikale Breite des Mondes = " + ekliptikaleBreiteMond (t) + "°");
		java.lang.System.out.println ("Mondphase = " + mondphase (t) + "%");
		java.lang.System.out.println ("Mondalter = " + mondalter (t) + "°");
	}
}