Klassen des Pakets AstroOL: Zur Doku-Startseite Zurück zur Homepage

Klasse Elements

Javadoc von Elements   Elements.java herunterladen

package AstroOL;

import java.io.*;
/** Datenklasse für die Berechnung der Bahnelemente.
    Diese Hilfsklasse von {@link LowPrecCalculator LowPrecCalculator}
    berechnet und puffert die angeforderten
    Bahnelemente der Planeten. Zentrale Methode ist
    die Methode {@link #get(double,int,double[]) get()}, die ein Array mit
    den Bahnelementen eines Planeten zu einer gegebenen
    Zeit zurückgibt.

    @see <a href="./doc-files/LowPrecCalculator.html">Datenmodell und die Kompressionsmethode des LowPrecCalculator</a>

    */
public class Elements {

// Verwaltungsdaten
  private static long jd_start = 0;
  private static long jd_end = 0;
  private static short increment;
// Arbeitsbereich mit Koeffizienten für quadratische Interpol.
  private static long jd_act; // Datum für erste Zeile des Arb.ber.
  private static double mAnomCoeff[][],deltaRCoeff[][];
// Koeffizienten für quadratische Regression
  private static double a[][][];
  private static double a0[][][];
// Verwaltungsdaten für Binärdaten mit mittl. Anomalien
  private static short min[][], max[][];
  private static byte size[][];
  private static int recordlength; // in Bit
// Binärdaten mit den mittleren Anomalien
  private static byte data[];

  static void readFile(int jahr0) {
     int bytesAvailable, planet, j;
     short n, m;
     byte i;
     InputStream in;
     DataInputStream din;
     byte int3[] = new byte[3]; // 3-Byte Integer
     String filename = "/rsc/data/J" +
         new Integer(10000 + jahr0).toString().substring(1,5) + ".dat";
// File öffnen, Daten lesen
    try {
      in = Elements.class.getResourceAsStream(filename);
      bytesAvailable = in.available();
//      System.out.println("Grösse:" + bytesAvailable + "\n");
      in.read(int3);
      jd_start = ( (int3[0] & 0xFF) << 16 ) + ( (int3[1] & 0xFF) << 8 ) + (int3[2] & 0xFF);
      in.read(int3);
      jd_end   = ( (int3[0] & 0xFF) << 16 ) + ( (int3[1] & 0xFF) << 8 ) + (int3[2] & 0xFF);
//      System.out.println("jd_start  = " + jd_start);
//      System.out.println("jd_end    = " + jd_end);
      din = new DataInputStream(in);
      increment = din.readShort();
//      System.out.println("increment = " + increment);
// Dann die Koeffizienten
     a0 = new double[3][7][2];
      for (planet = 0; planet < 3; planet++ )
        for (i = 0; i < 7; i++)
          for (j = 0; j < 2; j++) {
            a0[planet][i][j] = din.readDouble();
            }
     a = new double[5][7][3];
      for (planet = 0; planet < 5; planet++ )
        for (i = 0; i < 7; i++)
          for (j = 0; j < 3; j++) {
            a[planet][i][j] = din.readDouble();
            }

// Verwaltungsteil für mittlere Anomalien einlesen
      min = new short[2][5];
      max = new short[2][5];
      size = new byte[2][5];
      recordlength = 0;
      for (planet = 0; planet < 5; planet++ )
        for (j = 0; j < 2; j++ ) {
          min[j][planet] = din.readShort();
          max[j][planet] = din.readShort();
          m = 1;
          i = 0;
          n = (short) (max[j][planet] - min[j][planet]);
          while ( m <= n) { i++; m <<= 1; }
          size[j][planet] = i;
          recordlength += size[j][planet];
          }


// Nun Datenteil für mittl. Anomalien einlesen
      bytesAvailable = in.available();
      data = new byte[bytesAvailable];
      in.read(data);
      }
    catch(Exception e) {
      System.out.println("Fehler beim Oeffnen der Datei" + filename);
      return;
      }
  }


/** Bahnelemente von Planet x für Zeitpunkt jd berechnen.
    Dies ist die zentrale Methode der Klasse Elements. Sie gibt
    Bahnelemente für die Zeit jd und den Planeten planet zurück,
    die eine möglichst gute Positionsberechnung für den gewünschten
    Zeitpunkt gestatten. Die aktuelle Implementierung verwendet
    hierzu eine Binärdatei, die pro Jahrhundert ca. 4.7 KB umfasst.
    Die Datei enthält die linear regredierten Elemente aller Planeten
    sowie für die äusseren Planeten Korrekturterme für Radius
    und mittlere Anomalie. Der Korrekturterm für die mittlere Anomalie
    wird sofort angebracht. Der Korrekturterm für den Radius kann
    erst nach Lösung des Keplerproblems angebracht werden und wird
    daher als "8. Bahnelement" (d.h. an achter Stelle im Rückgabe-Array
    elements[]) zurückgereicht.
    @param jd Julianisches Datum (in Ephemeridenzeit)
    @param planet Nummer des Planeten. Die Numerierung der Planeten
    entspricht ihrer Reihenfolge (mit 0 = SO beginnend) im Attribut
    {@link Calculator#pknam Calculator.pknam}.
    @param elements Rückgabearray mit den Bahnelementen und dem
    Korrekturwert für den Radius. Die Reihenfolge ist
         <table align="center">
         <tr><td>Grosse Halbachse</td><td><code>= elements[0]</code></td></tr>
         <tr><td>Exzentrizität   </td><td><code>= elements[1]</code></td></tr>
         <tr><td>Bahnneigung     </td><td><code>= elements[2]</code></td></tr>
         <tr><td>Aufst. Knoten   </td><td><code>= elements[3]</code></td></tr>
         <tr><td>Perhihellänge   </td><td><code>= elements[4]</code></td></tr>
         <tr><td>Mittl. Anomalie </td><td><code>= elements[5]</code></td></tr>
         <tr><td>Tagesbewegung   </td><td><code>= elements[6]</code></td></tr>
         <tr><td>Korrektur für r </td><td><code>= elements[7]</code></td></tr>
         </table>
         */
public static void get( double jd, int planet,
                        double[] elements ) {
  int jahr0,i = planet - 5, j, k;
  double t;

  if ( (jd_start > jd) || (jd > jd_end) ) {
// Out of Range: Datenfile muss nachgelesen werden
     readFile((Calculator.calendarDate(jd)[0] - 50)/100*100+50);
     }

  t = ( jd - jd_start ) / increment;
  if (planet >= 5) {
    i = planet - 5;
    for (j = 0; j < 7; j++)
      elements[j] = ( a[i][j][2] * t + a[i][j][1] ) * t + a[i][j][0];
    }
  else {
    i = planet - 2;
    for (j = 0; j < 7; j++)
      elements[j] = a0[i][j][1] * ( t * 10 + 1 ) + a0[i][j][0];
    return;  // Keine Anomalie/Radiusdifferenzen verwendet
    }

// Anomalie / deltaR berechnen:

// Ist Arbeitsbereich nicht mehr verwendbar? Dann nachlesen
  if ( ( jd_act > jd ) || ( jd_act + 2*increment < jd) ) {
    get_workarea( jd );
    }

  t = (jd - jd_act ) / increment;
  elements[5] = Calculator.fmod(elements[5]+(( mAnomCoeff[2][i] * t + mAnomCoeff[1][i] )* t + mAnomCoeff[0][i])/1.e3,360.);
  elements[7] =  ( deltaRCoeff[2][i] * t + deltaRCoeff[1][i] )* t + deltaRCoeff[0][i];

}

private static void get_workarea( double jd ) {

  long offset, buffer = 0;
  byte size0, x, bits, i, k, pl;
  double x1,x2;

  if (mAnomCoeff  == null) mAnomCoeff = new double[3][5];
  if (deltaRCoeff == null) deltaRCoeff = new double[3][5];
// Arbeitsbereiche aus binärem Datenstrom einlesen
  offset = (long) ((jd - jd_start) / increment);
  jd_act = jd_start + increment * offset;
  offset *= recordlength;  // Bit-Offset
  for (i = 0; i < 3; i++ ) {       // 3 Zeiten
    for ( pl = 0; pl < 5; pl++ )   // 5 Planeten
      for ( k = 0; k < 2; k++ )  {     // 2 Zahlen ( Anomalie, deltaR )
        size0  = size[k][pl]; // so viele Bits müssen eingelesen werden
        buffer = 0;
        while ( size0 > 0 ) {
          x = (byte) ( data[(int) (offset / 8)] & ( 0xff >> ( offset % 8 ) ) ) ;
          bits = (byte) ( 8 - (offset % 8) ) ; // so viele Bits sind "eingelesen"
          if ( size0 < bits ) {
            x = (byte) ((x & 0xff) >> ( bits - size0 ));
            bits = size0;
            }
          buffer = ( buffer << bits ) + ( x & 0xff);
          size0 -= bits;
          offset += bits;
          }
// Nun sind size0 bits eingelesen, Ergebnis steht in buffer
        switch(k) {
          case 0:
            mAnomCoeff[i][pl] =  (double) min[k][pl] + buffer;
            break;
          case 1:
            deltaRCoeff[i][pl] = (double) min[k][pl] + buffer;
            break;
          }
        }
      }

// Koeffizienten für quadr. Polynom aufbereiten
// Funktion f an Stützstellen 0, 1, 2 durch Parabel interpolieren:
//
// q(x) =        f(0)
//      +  x   * ( 2*f(1) - (f(2)+3*f(0))/2 )
//      +  x^2 * ( -f(1)  + (f(2)+f(0))/2   )
//

  for (pl = 0; pl < 5; pl++) {
    x1 = mAnomCoeff[1][pl];
    x2 = mAnomCoeff[2][pl];
    mAnomCoeff[1][pl] = 2*x1 - ( x2 + 3*mAnomCoeff[0][pl] )/2;
    mAnomCoeff[2][pl] = ( x2 + mAnomCoeff[0][pl] ) / 2 - x1;
    x1 = deltaRCoeff[1][pl];
    x2 = deltaRCoeff[2][pl];
    deltaRCoeff[1][pl] = 2*x1 - ( x2 + 3*deltaRCoeff[0][pl] )/2;
    deltaRCoeff[2][pl] = ( x2 + deltaRCoeff[0][pl] ) / 2 - x1;
    }

  }

}


Zum Seitenanfang Lizenzbedingungen Der Quellcode wird mit dem GNU source-highlight 1.7 dargestellt