// MNeptune.PositionEquatorial(double) /// <summary> /// Liefert die (scheinbare) geozentrisch-äquatoriale Position zur julianischen Tageszahl. /// </summary> /// <param name="jd">Julianische Tageszahl.</param> /// <returns>Geozentrisch-äquatoriale Position zur julianischen Tageszahl.</returns> public static CPolar PositionEquatorial(double jd) { // Lokale Felder einrichten double bG = 0.0; // Geozentrische Breite. double bH = 0.0; // Heliozentrische Breite. double jdn = jd; // Julianische Tageszahl. double lG = 0.0; // Geozentrische Länge. double lH = 0.0; // Heliozentrische Länge. double rG = 0.0; // Geozentrischer Radius. double rH = 0.0; // Heliozentrischer Radius. double tau = 0.0; // Lichtlaufzeit. double tmp = 0.0; // Temporärwert. // ------------- // // Lichtlaufzeit // // ------------- // // Lichtlaufzeit iterieren while (true) { // Heliozentrische Position bestimmen bH = MNeptune.Latitude(EPrecision.High, jdn); lH = MNeptune.Longitude(EPrecision.High, jdn); rH = MNeptune.Radius(EPrecision.High, jdn); // Geozentrische Position berechnen und Abbruchbedinungen verarbeiten tmp = MEphemerides.ToGeocentric(lH, bH, rH, jdn, ref lG, ref bG, ref rG, EPrecision.High); if (MMath.Abs(tau - tmp) < 0.00005) { break; // Ausreichende Genauigkeit sicherstellen } if (tau != 0.0 && tmp >= tau) { break; // Abbruch bei Schwingung sicherstellen } // Wert anwenden und nächsten Iterationsschritt vorbereiten jdn += tmp; tau = tmp; } // ----------------------- // // Aberration und Nutation // // ----------------------- // // Aberation und Nutation anwenden MEphemerides.AberrationEcliptical(ref lG, ref bG, jdn); lG += MEphemerides.NutationInLongitude(jdn); bG += MEphemerides.NutationInObliquity(jdn); // ------------------------- // // Koordinatentransformation // // ------------------------- // // Äquatoriale Position berechnen und anwenden double a = MEphemerides.ToAlpha(lG, bG, EObliquity.True, jdn); double d = MEphemerides.ToDelta(lG, bG, EObliquity.True, jdn); return(new CPolar(a, d, rG)); }
// MNeptune.Transit(double, double, double, ref double) /// <summary> /// Setzt die Höhe und liefert die julianische Tageszahl des Meridiandurchgangs am geographischen Ort und zur julianischen Tageszahl. /// </summary> /// <param name="lambda">Geographische Länge.</param> /// <param name="phi">Geographische Breite.</param> /// <param name="jd">Julianische Tageszahl.</param> /// <param name="height">Höhe.</param> /// <returns>Julianische Tageszahl des Meridiandurchgangs am geographischen Ort und zur julianischen Tageszahl.</returns> public static double Transit(double lambda, double phi, double jd, ref double height) { // Lokale Felder einrichten double jdn = MMath.Floor(jd - 0.5) + 0.5; // Tageszahl um Mitternacht double l = 0.0; // Geozentrische Länge double b = 0.0; // Geozentrische Breite double a = 0.0; // Rektaszension double d = 0.0; // Deklination double dm = 1.0; // Korrekturglied // Position für nachfolgenden Tag berechnen l = MNeptune.Longitude(EPrecision.Low, jdn + 1.0); b = MNeptune.Latitude(EPrecision.Low, jdn + 1.0); double aP = MEphemerides.ToAlpha(l, b, EObliquity.Mean, jdn + 1.0); double dP = MEphemerides.ToDelta(l, b, EObliquity.Mean, jdn + 1.0); // Position für gegebenen Tag berechnen l = MNeptune.Longitude(EPrecision.Low, jdn); b = MNeptune.Latitude(EPrecision.Low, jdn); double a0 = MEphemerides.ToAlpha(l, b, EObliquity.Mean, jdn); if (MMath.Abs(aP - a0) > 1.0) { a0 += MMath.Sgn(aP - a0) * MMath.Pi2; } double d0 = MEphemerides.ToDelta(l, b, EObliquity.Mean, jdn); // Position für vorhergehenden Tag berechnen l = MNeptune.Longitude(EPrecision.Low, jdn - 1.0); b = MNeptune.Latitude(EPrecision.Low, jdn - 1.0); double aM = MEphemerides.ToAlpha(l, b, EObliquity.Mean, jdn - 1.0); if (MMath.Abs(a0 - aM) > 1.0) { aM += MMath.Sgn(a0 - aM) * MMath.Pi2; } double dM = MEphemerides.ToDelta(l, b, EObliquity.Mean, jdn - 1.0); // ------------------- // // Ereigniszeit nähern // // ------------------- // // Sternzeit und Stundenwinkel zum gegebenen Zeitpunkt bestimmen double t0 = MEphemerides.Gmst(jdn); double m = MMath.Div((aP + lambda - t0) / MMath.Pi2); if (m < 0.0) { m += 1.0; } // Ereigniszeit iterieren while (MMath.Abs(dm) >= 0.0001) { // Iteration durchführen und nächsten Iterationsschritt vorbereiten a = MMath.Bessel(m, aM, a0, aP); dm = MMath.Div((a + lambda - t0 - 6.300388093 * m) / MMath.Pi2); if (MMath.Abs(dm) > 0.5) { dm -= MMath.Sgn(dm); } m += dm; } // Iteration anwenden, Höhe berechnen und Rückgabewert setzen d = MMath.Bessel(m, dM, d0, dP); height = MEphemerides.ToHeight(0.0, d, phi); return(jd + m); }
// MNeptune.Set(double, double, ref double, double, ref double) /// <summary> /// Setzt die julianische Tageszahl des Untergangs und die Abendweite am geographischen Ort und zur julianischen Tageszahl und liefert die Ereigniskennung. /// </summary> /// <param name="lambda">Geographische Länge.</param> /// <param name="phi">Geographische Breite.</param> /// <param name="jdEvent">Julianische Tageszahl des Untergangs.</param> /// <param name="jd">Julianische Tageszahl.</param> /// <param name="azimuth">Abendweite.</param> /// <returns>Ereigniskennung.</returns> public static EEventType Set(double lambda, double phi, ref double jdEvent, double jd, ref double azimuth) { // Lokale Felder einrichten double jdn = MMath.Floor(jd - 0.5) + 0.5; // Tageszahl um Mitternacht double l = 0.0; // Geozentrische Länge double b = 0.0; // Geozentrische Breite double a = 0.0; // Rektaszension double d = 0.0; // Deklination double dm = 1.0; // Korrekturglied double h = 0.0; // double h0 = MEphemerides.GeocentricHeight_Star; // Refraktionswinkel double H = 0.0; // double sinP = MMath.Sin(phi); // Breitensinus double cosP = MMath.Cos(phi); // Breitencosinus // Position für nachfolgenden Tag berechnen l = MNeptune.Longitude(EPrecision.Low, jdn + 1.0); b = MNeptune.Latitude(EPrecision.Low, jdn + 1.0); double aP = MEphemerides.ToAlpha(l, b, EObliquity.Mean, jd + 1.0); double dP = MEphemerides.ToDelta(l, b, EObliquity.Mean, jd + 1.0); // Position für gegebenen Tag berechnen l = MNeptune.Longitude(EPrecision.Low, jdn); b = MNeptune.Latitude(EPrecision.Low, jdn); double a0 = MEphemerides.ToAlpha(l, b, EObliquity.Mean, jdn); if (MMath.Abs(aP - a0) > 1.0) { a0 += MMath.Sgn(aP - a0) * MMath.Pi2; } double d0 = MEphemerides.ToDelta(l, b, EObliquity.Mean, jdn); // Position für vorhergehenden Tag berechnen l = MNeptune.Longitude(EPrecision.Low, jdn - 1.0); b = MNeptune.Latitude(EPrecision.Low, jdn - 1.0); double aM = MEphemerides.ToAlpha(l, b, EObliquity.Mean, jd - 1.0); if (MMath.Abs(a0 - aM) > 1.0) { aM += MMath.Sgn(a0 - aM) * MMath.Pi2; } double dM = MEphemerides.ToDelta(l, b, EObliquity.Mean, jd - 1.0); // Stundenwinkel berechnen und prüfen double cosH = (MMath.Sin(h0) - sinP * MMath.Sin(dP)) / (cosP * MMath.Cos(dP)); if (MMath.Abs(cosH) > 1.0) { return(cosH < 1.0 ? EEventType.AlwaysAboveHorizon : EEventType.AlwaysBeneathHorizon); } H = MMath.ArcCos(cosH); // ------------------- // // Ereigniszeit nähern // // ------------------- // // Sternzeit und Stundenwinkel zum gegebenen Zeitpunkt bestimmen double t0 = MEphemerides.Gmst(jdn); double m = MMath.Div((a0 + lambda - t0 + H) / MMath.Pi2); if (m < 0.0) { m += 1.0; } // Ereigniszeit iterieren while (MMath.Abs(dm) >= 0.0001) { // Iteration durchführen und nächsten Iterationsschritt vorbereiten a = MMath.Bessel(m, aM, a0, aP); d = MMath.Bessel(m, dM, d0, dP); H = t0 + 6.300388093 * m - lambda - a; h = MMath.ArcSin(sinP * MMath.Sin(d) + cosP * MMath.Cos(d) * MMath.Cos(H)); dm = (h - h0) / (MMath.Pi2 * MMath.Cos(d) * cosP * MMath.Sin(H)); m += dm; } // Iteration anwenden, Azimut berechnen und Rückgabewert setzen jdEvent = jd + m; azimuth = MEphemerides.ToAzimuth(H, d, phi); return(EEventType.Normal); }
// MMoon.NewMoon(double, ref EEclipseType) /// <summary> /// Setzt die Kennung der Finsternisabschätzung und liefert die julianische Tageszahl des nächsten Neumondes nach der julianischen Tageszahl. /// </summary> /// <param name="jd">Julianische Tageszahl.</param> /// <param name="type">Kennung der Finsternisabschätzung.</param> /// <returns>Julianische Tageszahl des nächsten Neumondes nach der julianischen Tageszahl.</returns> public static double NewMoon(double jd, ref EEclipseType type) { // Lokale Felder einrichten und Ereigniszeit berechen double y = (double)MCalendar.GregorianYear(jd) + MEphemerides.YearFragment(jd); double k = MMath.Floor(12.3685 * (y - 2000.0)) - 1.0; double j = 0.0; // Berechnungsschleife while (j <= jd) { // Lunation inkrementieren und lokale Felder einrichten k += 1.0; double t = k / 1236.85; // Näherung berechnen und Hilfsfelder einrichten j = MMath.Polynome(t, 2451550.09766 + 29.530588861 * k, 0.0, 0.00015437, -0.000000150, 0.00000000073); double e1 = MMath.Polynome(t, 1.0, -0.002516, -0.0000074); double e2 = e1 * e1; double m = MMath.Mod(MMath.ToRad(MMath.Polynome(t, 2.5534 + 29.10535670 * k, 0.0, -0.0000014, -0.00000011)), MMath.Pi2); double a = MMath.Mod(MMath.ToRad(MMath.Polynome(t, 201.5643 + 385.81693528 * k, 0.0, 0.0107582, 0.00001238, -0.000000058)), MMath.Pi2); double f = MMath.Mod(MMath.ToRad(MMath.Polynome(t, 160.7108 + 390.67050284 * k, 0.0, -0.0016118, -0.00000227, 0.000000011)), MMath.Pi2); double o = MMath.Mod(MMath.ToRad(MMath.Polynome(t, 124.7746 - 1.56375588 * k, 0.0, 0.0020672, 0.00000215)), MMath.Pi2); double h; // Korrektur berechnen h = -0.40720 * MMath.Sin(a); h += 0.17241 * e1 * MMath.Sin(m); h += 0.01608 * MMath.Sin(2.0 * a); h += 0.01039 * MMath.Sin(2.0 * f); h += 0.00739 * e1 * MMath.Sin(a - m); h += -0.00514 * e1 * MMath.Sin(a + m); h += 0.00208 * e2 * MMath.Sin(2.0 * m); h += -0.00111 * MMath.Sin(a - 2.0 * f); h += -0.00057 * MMath.Sin(a + 2.0 * f); h += 0.00056 * e1 * MMath.Sin(2.0 * a + m); h += -0.00042 * MMath.Sin(3.0 * a); h += 0.00042 * e1 * MMath.Sin(m + 2.0 * f); h += 0.00038 * e1 * MMath.Sin(m - 2.0 * f); h += -0.00024 * e1 * MMath.Sin(2.0 * a - m); h += -0.00017 * MMath.Sin(o); h += -0.00007 * MMath.Sin(a + 2.0 * m); h += 0.00004 * MMath.Sin(2.0 * a - 2.0 * f); h += 0.00004 * MMath.Sin(3.0 * m); h += 0.00003 * MMath.Sin(a + m - 2.0 * f); h += 0.00003 * MMath.Sin(2.0 * a + 2.0 * f); h += -0.00003 * MMath.Sin(a + m + 2.0 * f); h += 0.00003 * MMath.Sin(a - m + 2.0 * f); h += -0.00002 * MMath.Sin(a - m - 2.0 * f); h += -0.00002 * MMath.Sin(3.0 * a + m); h += 0.00002 * MMath.Sin(4.0 * a); // Störungen durch Planeten berechnen h += 0.000325 * MMath.Sin(MMath.ToRad(299.77 + 0.107408 * k - 0.009173 * t * t)); h += 0.000165 * MMath.Sin(MMath.ToRad(251.88 + 0.016321 * k)); h += 0.000164 * MMath.Sin(MMath.ToRad(251.83 + 26.651886 * k)); h += 0.000126 * MMath.Sin(MMath.ToRad(349.42 + 36.412478 * k)); h += 0.000110 * MMath.Sin(MMath.ToRad(84.66 + 18.206239 * k)); h += 0.000062 * MMath.Sin(MMath.ToRad(141.74 + 53.303771 * k)); h += 0.000060 * MMath.Sin(MMath.ToRad(207.14 + 2.453732 * k)); h += 0.000056 * MMath.Sin(MMath.ToRad(154.84 + 7.306860 * k)); h += 0.000047 * MMath.Sin(MMath.ToRad(34.52 + 27.261239 * k)); h += 0.000042 * MMath.Sin(MMath.ToRad(207.19 + 0.121824 * k)); h += 0.000040 * MMath.Sin(MMath.ToRad(291.34 + 1.844379 * k)); h += 0.000037 * MMath.Sin(MMath.ToRad(161.72 + 24.198154 * k)); h += 0.000035 * MMath.Sin(MMath.ToRad(239.56 + 25.513099 * k)); h += 0.000023 * MMath.Sin(MMath.ToRad(331.55 + 3.592518 * k)); // Korrekturen anwenden j += h; } // Ekliptikale Breite berechnen und Finsternisabschätzung bestimmen double b = MMath.Abs(MMoon.Latitude(EPrecision.Medium, j)); if (b < 0.015223) { type = EEclipseType.SunCentralDefinite; } else if (b < 0.018210) { type = EEclipseType.SunCentralPotential; } else if (b < 0.024595) { type = EEclipseType.SunPartialDefinite; } else if (b < 0.027586) { type = EEclipseType.SunPartialPotential; } else { type = EEclipseType.SunNoEclipse; } return(j); }