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

Klasse LowPrecCalculator

Javadoc von LowPrecCalculator   LowPrecCalculator.java herunterladen

package AstroOL;
import java.util.*;

/** Die Klasse LowPrecCalculator ergänzt
die Klasse Calculator um explizite Methoden zur Berechnung
der Planeten und Häuser. Die Berechnungen, die
von der Calculator-Klasse normalerweise mittels eines Servlets im Backend
ausgeführt werden, sind im LowPrecCalculator konkret
ausprogrammiert.
<p>
Wie Calculator hat auch LowPrecCalculator den Zweck, astrologische
Berechnungen effizient durchzuführen. Sie ist jedoch als Standalone
Version gedacht, die auch offline verwendbar ist.- Um sie dennoch
kompakt und schnell zu halten, wurde von den hohen Genauigkeitsansprüchen
der Swiss Ephemeris abgerückt: Der LowPrecCalculator rechnet Planetenstände
auf die Bogenminute genau, nur die Sonne ist auf die Bogensekunde genau,
so dass auch Solarberechnungen möglich sind.
<p> LowPrecCalculator erbt von Calculator, so dass keine doppelte Logik
programmiert werden musste. Die meisten Hilfsfunktionen existierten
bereits in der Nachfolgefunktion oder konnten leicht in diese übernommen
werden.
@see <a href="./doc-files/LowPrecCalculator.html">Datenmodell und die Kompressionsmethode des LowPrecCalculator</a>
*/
public class LowPrecCalculator extends Calculator implements ICalculator {


/** Umwandlungsfaktor Sternzeit in Weltzeit */
     public static final double ST_UT   = .10027379093e1;
/** Reziprokwert der Lichtgeschwindigkeit in d/AE */
     public static final double cInvers = .57755183044121e-2;
/** Naibodschlüssel (mittlere Bewegung der Sonne am Tag) */
     public static final double naibod  = .9856473e0;

/** Gibt an, ob Aberration und
    Lichtlaufzeit berücksichtigt werden sollen.
    Ist es gesetzt, so werden Aberration und Lichtlaufzeit
    nicht berücksichtigt. Man erhält die geometrischen
    Planetenpositionen
    */
    public static boolean geometric = false;

/** Verwendetes Häusersystem. */
    public static byte hSystem = Mundan.PLACIDUS;


/** Julianisches Datum der Instanz (in Ephemeridenzeit) */
     public double        xjd;
/** Weltzeit der Instanz */
     public double        ut;
/** Geographische Länge der Instanz (in Grad).
    Östliche Längen werden positiv, westliche negativ gerechnet.
    */
     public double        lon = 8.55;
/** Geographische Breite der Instanz (in Grad).
    Nördliche Breiten werden positiv,
    südliche negativ gerechnet. */
     public double        lat = 47.366;
/** Rektaszension des Medium Coeli (RAMC) in Grad.
    Dies ist derselbe Wert wie die in Grad umgerechnete
    Ortssternzeit (LST) */
     public double        ramc;
/** Schiefe der Ekliptik zur Instanz in Grad */
     public double        ee;
/** Häuserspitzen.
    Es ist
    <table align="center">
    <tr><td>h[1]  </td><td>= Aszendent,</td></tr>
    <tr><td>h[4]  </td><td>= I.C.,</td></tr>
    <tr><td>h[7]  </td><td>= Deszendent,</td></tr>
    <tr><td>h[10] </td><td>= M.C.,</td></tr>
    <tr><td>h[i]  </td><td>= i. Häuserspitze</td></tr>
    </table>
    in der in der Astrologie üblichen Zählweise.
    */
     public double        h[];
/** Ekliptikale Längen der Planeten.
    Die Indizierung entspricht der Reihenfolge (mit 0 = SO beginnend)
    im String {@link Calculator#pknam Calculator.pknam}. */
     public double        pl[];

/** Ekliptikale Breiten der Planeten.
    Die Indizierung entspricht der Reihenfolge (mit 0 = SO beginnend)
    im String {@link Calculator#pknam Calculator.pknam}. */
     public double        pb[];


/** Der leere Konstruktor instanziiert zum aktuellen Datum.
    Als Ort wird Zürich zugrundegelegt */
  public LowPrecCalculator() {
         xjd = thisjd();
         construct();
         }

/** Konstruktor mit Julianischem Datum, geographischer Länge und Breite
    @param xjd Julianisches Datum in ET
    @param lon Geographische Länge
    @param lat Geographische Breite
    */
  public LowPrecCalculator(double xjd, double lon, double lat) {
    this.xjd = xjd;
    this.lon = lon;
    this.lat = lat;
    construct();
    }

/** Konstruktor mit Zeit/Ort String.
    @param in Eingabestring für Datum, Uhrzeit und Ort.
    Zum Format des Strings
    siehe die Methode {@link Calculator#parseTimePlace(String,double[])
    Calculator.parseTimePlace()}
    */
  public LowPrecCalculator(String in) {
       double[] tp = new double[3];
       if (!in.equals("") && !in.equalsIgnoreCase("now") && parseTimePlace(in,tp)) {
         lon = tp[1];
         lat = tp[2];
         xjd = tp[0];
         }
       else
         xjd = thisjd();
       construct();
    }

/** Berechnung der Häuser und Planeten.
    Diese Methode wird aus dem Konstruktor aufgerufen */
   private void construct() {
        pl = new double[10];
        pb = new double[10];
        h  = new double[13];
        construct(pl,pb,h);
	}

   private void construct(double[] pl, double[] pb, double[] h) {

        byte i;
        double[][] lbr = new double[10][3];
        Mundan m;

        compute(xjd, lbr);
        for (i = 0; i < 10; i++) {
          pl[i] = lbr[i][0];
          pb[i] = lbr[i][1];
          }
        ut = (xjd + .5 - Math.floor(xjd + .5) - deltat(xjd))*24;
        ee = tilt();
        ramc = lst();
        m = new Mundan( ramc, lat, ee, hSystem);
        for (i = 0; i < 12; i++)
          h[i+1] = m.hauslaenge(i*30d);

      }


/** Implementierung der Methode ICalculator.getPlanetsAndHouses() */
     public boolean getPlanetsAndHouses( double iXjd,
                                         double iLon,
                                         double iLat,
	                                     double[] cPl,
                                         double[] cH) {
        this.xjd = iXjd;
        this.lon = iLon;
        this.lat = iLat;
        pb = new double[10];
        pl = cPl;
        h  = cH;
        construct(pl,pb,h);
	    return true;
       }


/** Leere Implementierung, da diese Klasse kein Backend benötigt */
    public void setServletURL(String iServletURL) {
      }

/** Korrektur zur Umrechnung Weltzeit (UT) in Ephemeridenzeit (ET).
    Es wird eine Nährungsformel von Stephenson und
    Morrison (Sun and Planetary System vol. 96 (1982), p.73)
    verwendet.
    Es gilt ET = UT + Delta T.
    @param xjd Julianisches Datum
    @return Korrektur in Tagen
    */
     public static double deltat(double xjd) {
       return 2.81961082534138505e-13
          * (-2.406934851e6+xjd)
          * (-2.357307148e6+xjd)  ;
       }

/** Ausgabe der Attribute einer Calculator-Instanz */
     public String toString() {
        StringBuffer s = new StringBuffer();
        s.append("Julianisches Datum:    " + Double.toString(xjd) + "\n");
        int[] ymd = calendarDate(xjd);
        s.append("Kalenderdatum:         " + ymd[2]+"."+ymd[1]+"."+ymd[0] + "\n");
        s.append("Geographische Laenge: " + dms(lon,LONG) + "\n");
        s.append("Geographische Breite:  " + dms(lat,LAT) + "\n");
        s.append("Aszendent:             " + dms(h[1],ECL | SEC) + "\n");
        s.append("Medium Coeli:          " + dms(h[10],ECL | SEC) + "\n");
        s.append("Haus 2:                " + dms(h[2],ECL | SEC) + "\n");
        s.append("Haus 3:                " + dms(h[3],ECL | SEC) + "\n");
        s.append("Haus 11:               " + dms(h[11],ECL | SEC) + "\n");
        s.append("Haus 12:               " + dms(h[12],ECL | SEC) + "\n");
        for ( int i = 0; i < 10; i++ )
          s.append(pknam.substring(2*i,2*i+2) + ":  " + dms(pl[i]) + "\n");
        return s.toString(); }


/** Bogensekundengenaue Sonnenposition nach einer Reihenentwicklung
    von S. Newcomb.
    @param jd Julianisches Datum in Ephemeridenzeit
    @return Polarkoordinaten der Sonne (Länge, Breite, Radius)
    in dieser Reihenfolge
    */
      public static double[] newcomb (double jd)
      {
      double t,t1,dlp,l0,l01,g,g2,g4,g5,g6,d,a_,u,dl,r0,dl2,dl4,dl5,dl6;
      double dlm,l,dr2,dr4,dr5,dr6,drm,r,lx,bx,rx;
      double lbr[] = { 0.,0.,0. };
      t1 = jd - (double)2415020.;
      t = t1/(double)36525.;
/*c --- long periodic disturbation */
      dlp = ((double)1.882e0-(double).016*t)*
	    sin((double)57.24  + (double)150.27*t)
          + (double) 6.4           *sin(231.19e0 +  20.20*t)
          + (double)0.266          *sin( 31.8e0  + 119.00*t);
/*c --- mean longitude sun */
      l0  = 279.6966778e0 + 360.*fract(t1/(double)365.25);
      l01 = 2768.13*t + 1.089*t*t + 0.202*sin(315.6e0+893.3*t)+dlp;
      l0  = l0 + l01/3600.e0;
/*c --- mean anomaly sun */
      g   = 358.475833e0
          + 360.e0*fract(t1*(double).0027104722792607802874743)
          + t1*(double).009828884325804243668
	  + ( 179.1*t - .54*t*t + dlp )/3600.e0;
/*c --- mean anomaly venus,mars,jupiter,saturn */
      g2  = 212.45e0 + 360.*fract(t1*(double).004435318275154004107)
	  + t1*(double).0054070636650308;
      g4  = 319.58e0 + t1*(double).524024010951403;
      g5  = 225.28e0 + t1*(double).0830823545516769336
	  + (double).3611111111111111111* sin(133.775e0 + 39.804*t);
      g6  = 175.6e0  + t1*(double).03345089664613278576;
/*c --- moon data */
      d   = 350.737486e0 + t1*(double).00840832900752909
	  + 360.*fract(t1*(double).033839835728952772);
      a_  = 296.104608e0 + t1*(double).005444191868583162
	  + 360.*fract(t1*(double).0362765229295003422);
      u   =  11.250889e0 + t1*(double).00224572621492128
	  + 360.*fract(t1*(double).03674195756331279945);
/*c --- terms of two body motion */
      dl  = (6910.057e0 - 17.240e0*t)*sin(   g )
          + (  72.338e0 -   .361e0*t)*sin(2.e0*g)
          +                1.054e0*t *sin(3.e0*g );
      r0  = ( .00003057e0  -  0.00000015*t)
          + (-.00727412e0  +  0.00001814*t)*cos( g )
          + (-.00009138e0  +  0.00000046*t)*cos( 2.e0*g )
                           -  0.00000145   *cos( 3.e0*g );
/*c --- perturbations in longitude */
      dl2 = 4.838*cos(299.102e0 +    g2 -    g)
          + 0.116*cos(148.900e0 + 2.*g2 -    g)
          + 5.526*cos(148.313e0 + 2.*g2 - 2.*g)
          + 2.497*cos(315.943e0 + 2.*g2 - 3.*g)
          + 0.666*cos(177.710e0 + 3.*g2 - 3.*g)
          + 1.559*cos(345.243e0 + 3.*g2 - 4.*g)
          + 1.024*cos(318.150e0 + 3.*g2 - 5.*g)
          + 0.210*cos(206.200e0 + 4.*g2 - 4.*g)
          + 0.144*cos(195.400e0 + 4.*g2 - 5.*g)
          + 0.152*cos(343.800e0 + 4.*g2 - 6.*g)
          + 0.123*cos(195.300e0 + 5.*g2 - 7.*g)
          + 0.154*cos(359.600e0 + 5.*g2 - 8.*g);
/*c */
      dl4 = 0.273*cos(217.700e0 -    g4 +    g)
          + 2.043*cos(343.888e0 - 2.*g4 + 2.*g)
          + 1.770*cos(200.402e0 - 2.*g4 +    g)
          + 0.129*cos(294.200e0 - 3.*g4 + 3.*g)
          + 0.425*cos(338.800e0 - 3.*g4 + 2.*g)
          + 0.500*cos(105.180e0 - 4.*g4 + 3.*g)
          + 0.585*cos(334.060e0 - 4.*g4 + 2.*g)
          + 0.204*cos(100.800e0 - 5.*g4 + 3.*g)
          + 0.154*cos(227.400e0 - 6.*g4 + 4.*g)
          + 0.101*cos( 96.300e0 - 6.*g4 + 3.*g)
          + 0.106*cos(222.700e0 - 7.*g4 + 4.*g);
/*c */
      dl5 = 0.163*cos(198.600e0 -    g5 + 2.*g)
          + 7.208*cos(179.532e0 -    g5 +    g)
          + 2.600*cos(263.217e0 -    g5       )
          + 2.731*cos( 87.145e0 - 2.*g5 + 2.*g)
          + 1.610*cos(109.493e0 - 2.*g5 +    g)
          + 0.164*cos(170.500e0 - 3.*g5 + 3.*g)
          + 0.556*cos( 82.650e0 - 3.*g5 + 2.*g)
          + 0.210*cos( 98.500e0 - 3.*g5 +    g);
/*c */
      dl6 = 0.419*cos(100.580e0 -    g6 +    g)
          + 0.320*cos(269.460e0 -    g6       )
          + 0.108*cos(290.600e0 - 2.*g6 + 2.*g)
          + 0.112*cos(293.600e0 - 2.*g6 +    g);
/*c */
      dlm = 6.454*sin(d)
          + 0.177*sin(d+a_)
          - 0.424*sin(d-a_)
          + 0.172*sin(d-g);
/*c
c --- now sum up to true longitude
c */
      l = dl + dl2 + dl4 + dl5 + dl6 + dlm ;
      lbr[0] = fmod(l/.36e4 + l0,.36e3);
/*c
c --- ecliptical latitude
c */
      bx= -0.210*cos(151.800e0 + 3.*g2 - 4.*g )
          -0.166*cos(265.500e0 - 2.*g5 +    g )
          +0.576*sin(u);
      lbr[1] = bx/3600.;
/*c
c --- radius vector
c */
      dr2 = 2359*cos(209.080 +   g2 -  g)
          +  160*cos( 58.400 + 2*g2 -  g)
          + 6842*cos( 58.318 + 2*g2 - 2*g)
          +  869*cos(226.700 + 2*g2 - 3*g)
          + 1045*cos( 87.570 + 3*g2 - 3*g)
          + 1497*cos(255.250 + 3*g2 - 4*g)
          +  194*cos( 49.500 + 3*g2 - 5*g)
          +  376*cos(116.280 + 4*g2 - 4*g)
          +  196*cos(105.200 + 4*g2 - 5*g)
          +  163*cos(145.400 + 5*g2 - 5*g)
          +  141*cos(105.400 + 5*g2 - 7*g);
/*c */
      dr4 =  150*cos(127.700 -   g4 +   g)
          + 2057*cos(253.828 - 2*g4 + 2*g)
          +  151*cos(295.000 - 2*g4 +   g)
          +  168*cos(203.500 - 3*g4 + 3*g)
          +  215*cos(249.000 - 3*g4 + 2*g)
          +  478*cos( 15.170 - 4*g4 + 3*g)
          +  105*cos( 65.900 - 4*g4 + 2*g)
          +  107*cos(324.600 - 5*g4 + 4*g)
          +  139*cos(137.300 - 6*g4 + 4*g);
/*c */
      dr5 =  208*cos(112.000 -   g5 + 2*g)
          + 7067*cos( 89.545 -   g5 +   g)
          +  244*cos(338.600 -   g5      )
          +  103*cos(350.500 - 2*g5 + 3*g)
          + 4026*cos(357.108 - 2*g5 + 2*g)
          + 1459*cos( 19.467 - 2*g5 + 1*g)
          +  281*cos( 81.200 - 3*g5 + 3*g)
          +  803*cos(352.560 - 3*g5 + 2*g)
          +  174*cos(  8.600 - 3*g5 + 1*g)
          +  113*cos(347.700 - 4*g5 + 2*g);
/*c */
      dr6 =  429*cos( 10.600 -   g6 +   g)
          +  162*cos(200.600 - 2*g6 + 2*g)
          +  112*cos(203.100 - 2*g6 +   g);
/*c */
      drm =13360*cos(d)
          +  370*cos(d+a_)
          - 1330*cos(d-a_)
          -  140*cos(d+g)
          +  360*cos(d-g);
      r   = r0 + 1.e-9*(dr2+dr4+dr5+dr6+drm);
      lbr[2] = Math.pow(0.1e2,r);

      return lbr;

      }

/** Mondephemeride nach Brown.
    Es wird die Mondposition zur Ephemeridenzeit jd
    berechnet. Das Resultat ist in Länge auf 1-2 Bogenminuten
    genau.
    @param jd Julianisches Datum in ET (Ephemeridenzeit)
    @return Mondposition in Polarkoordinaten (Länge, Breite, Radiusvektor)
    */
      public static double[] brown (double jd)
      {

      double w,xnut_,day,xl,yl,xp,yp,xn,al,bl,ap,bp,an,
      u,v,f,d,dl,e;
      double lbn[] = { 0., 0., 0. };

      w=(jd-2415020.e0)/36525.e0;
      xnut_ = -17.2327/1296000.*Math.sin((259.18-1934.142*w)*toRad);
      day=jd-2415020.e0;
      xl=.751206e0 +day*.0366011014634e0;
      yl=.776935e0 +day*.0027379092649e0;
      xp=.928693e0 +day*.0003094557786e0;
      yp=.781169e0 +day*.0000001307457e0;
      xn=.719954e0 -day*.0001470942283e0;
      al=fract(xl)*2*Math.PI;
      bl=fract(yl)*2*Math.PI;
      ap=fract(xp)*2*Math.PI;
      bp=fract(yp)*2*Math.PI;
      an=fract(xn)*2*Math.PI;
      u=al-ap;
      v=bl-bp;
      f=al-an;
      d=al-bl;
      dl=22639*Math.sin(u)-4586*Math.sin(u-d-d)+2370*Math.sin(d+d)+769*Math.sin(u+u)
      -668*Math.sin(v)-412*Math.sin(f+f)-212*Math.sin(u+u-d-d)-206*Math.sin(u+v-d-d)
      +192*Math.sin(u+d+d)-165*Math.sin(v-d-d)+148*Math.sin(u-v)-125*Math.sin(d)
      -110*Math.sin(u+v)-55*Math.sin(f+f-d-d)-45*Math.sin(u+f+f)+40*Math.sin(u-f-f)
      -38*Math.sin(u-4*d)+36*Math.sin(3*u)-31*Math.sin(u+u-4*d)+28*Math.sin(u-v-d-d)
      -24*Math.sin(v+d+d)+19*Math.sin(u-d)+18*Math.sin(v+d)+15*Math.sin(u-v+d+d)
      +14*Math.sin(4*d)+14*Math.sin(u+u+d+d)-13*Math.sin(3*u-d-d);
      xl += dl/1296000.+xnut_;
      lbn[0]  = fract(xl)*360.e0;
      lbn[1]  = (18461*Math.sin(f)+1010*Math.sin(u+f)-1000*Math.sin(f-u)
      -624*Math.sin(f-2*d)-167*Math.sin(u+f-d-d)+199*Math.sin(f-u+d+d)
      +117*Math.sin(f+d+d)+62*Math.sin(u+u+f)-33*Math.sin(f-u-d-d)
      -32*Math.sin(f-u-u)-30*Math.sin(v+f-d-d)-16*Math.sin(u+u+f-d-d)
      +15*Math.sin(u+f+d+d)+12*Math.sin(f-v-d-d)+9*Math.sin(f-u-v+d+d))/3600.;
      lbn[2]  = fmod(an/6.28318531,1.e0)*360.e0;
      return lbn;
      }

     /** Löst das Keplerproblem.
         Im Array elements[] werden die Bahnelemente sowie
         ein Korrekturterm für den Radiusvektor
         übergeben. Als Rückgabewert erhält man einen Array mit
         den Polarkoordinaten der Lösung des Keplerproblems.
         @param elements Bahnelemente. Übergeben werden
         <table>
         <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 double[] kepler ( double[] elements )
      {

      boolean firstTime = true;
      double lbr[] = { 0., 0., 0. };
      double m = elements[5]*toRad;
      double inc1 = elements[2]*toRad;
      double omega1 = elements[4]*toRad;
      double node1 = elements[3]*toRad;
      double denom,e0,e,u;

      e0 = m;
      e = 0;
/*1*/ while ( ( Math.abs(e-e0) > 1.e-7 ) || firstTime ) {
        firstTime = false;
        e = e0;
        denom = elements[1]*Math.cos(e)-1.;
        e0 = e - (m-e+elements[1]*Math.sin(e))/denom;
        }
      u = Math.sqrt((1.+elements[1])/(1.-elements[1]))*Math.sin(e/2.);
      u = Math.atan2(u,Math.cos(e/2.))*2.;
      u = u + omega1 - node1;
      u = fmod(u,2*Math.PI);
      lbr[2] = elements[0]*(1.-elements[1]*Math.cos(e));
      lbr[1] = Math.asin(Math.sin(u)*Math.sin(inc1))*toDeg;
      lbr[0] = Math.atan2(Math.sin(u)*Math.cos(inc1),Math.cos(u)) + node1;
      lbr[0] = fmod(lbr[0]*toDeg, 360.);
      return lbr;
      }

/** Berechnet die Nutationskorrektur, die an die geozentrischen
    Längen zur mittleren Ekliptik des Datums anzubringen ist, um
    die sogenannten wahren Längen zu bekommen
    @param jd Julianisches Datum
    @return Nutationskorrektur in Grad */
      public static double nutation( double jd )
      {
      double t,lm,m,an,ls,ms,nut;
      t = (jd - .2451545e7)/.36525e5;
      lm = 218.316 + .481267881e6*t;
      m = 134.963 + .477198867e6*t;
      an = 125.045 - .1934136e4*t;
      ls = 280.466 + .36000770e5*t;
      ms = 357.528 + .35999050e5*t;
      nut = - .172e2*Math.sin(an*toRad)    -.1319e1*Math.sin(2*ls*toRad)
           - .227e0*Math.sin(2*lm*toRad)  +.2060e0*Math.sin(2*an*toRad)
           + .143e0*Math.sin(ms*toRad)    +.071e0*Math.sin(m*toRad);
      return nut/3600.;
      }

/** Berechnet die Nutationskorrektur, die an die geozentrischen
    Längen zur mittleren Ekliptik des Datums anzubringen ist, um
    die sogenannten wahren Längen zu bekommen.
    <p>Dies ist die Instanzmethode nutation(). Sie berechnet die
    Korrektur für das Julianische Datum der Instanz.
    @return Nutationskorrektur in Grad */
      public double nutation() {
        return nutation(xjd);
        }

/** Mittlere Schiefe der Ekliptik berechnen.
    @param jd Julianisches Datum
    @return Mittlere Schiefe der Ekliptik in Grad
    */
     public static double tilt( double jd)
       {
        return .2343929166e2-.4682e2*(jd-.2451545e7)/.36525e5/.36e4;
       }

/** Instanzmethode zur Berechnung der Schiefe der Ekliptik.
    Es wird das Datum der Instanz zugrundegelegt.
    @return Mittlere Schiefe der Ekliptik in Grad
    */
     public double tilt()
       {
        return tilt( xjd );
       }

/** Greenwich Sternzeit (in Grad, also die RAMC) um 0h Weltzeit berechnen.
    @param jd Julianisches Datum
    @return  RAMC */
      public static double gst0(double jd)
        {

        double t,y,rc;

        y = Math.floor(jd-.5)+.5;
        t = (y-2451545.)/36525.;
        rc = ((-.0000062*t + .093104)*t +184.812866)*t  ;
        rc = 6.697374558 +24.*(100.*t-Math.floor(100.*t)) + rc/3600.;
        return( fmod(rc*15.,360.));
        }

/** RAMC aus:
    <ul>
    <li>Greenwich-Sternzeit um 0 Uhr,
    <li>Weltzeit und
    <li>östl. Länge
    </ul>
    berechnen.
    @param st0 Greenwich-Sternzeit (RAMC) um 0 Uhr Weltzeit, z.B.
    mit der Methode {@link #gst0(double) gst0()} berechnet.
    @param ut Weltzeit in Stunden
    @param laenge geographische Länge in Grad
    @return Ortssternzeit in Grad ( = RAMC ) */
    public static double lst(double st0, double ut, double laenge)
     {
     double x;
     x=st0  +ut*ST_UT*15.;
     x+=  laenge;
     return (fmod(x,360d));
     }

/** Instanzmethode zur Methode {@link LowPrecCalculator#lst(double,double,double) lst(st0,ut,laenge)}.
    Es werden das Datum (xjd) und die Weltzeit (ut) der Instanz
    zugrundegelegt.
    @return Ortssternzeit in Grad ( = RAMC ).
    */
     public double lst() {
       return lst( gst0(xjd), ut, lon );
       }

/** Cartesische in Polarkoordinaten umwandeln. */
     public static double[] carpo ( double[] car )
      {
      double rho;
      double[] lbr = new double[3];
      lbr[2] = Math.sqrt( car[0]*car[0] + car[1]*car[1] + car[2]*car[2] );
      rho = Math.sqrt(car[0]*car[0] + car[1]*car[1]);
      if (rho == 0.) {
	      lbr[0] = 0.;
        if (car[2] > 0.) lbr[1] = 90;
	      if (car[2] < 0.) lbr[1] = -90;
      	if (car[2] == 0.) lbr[1] = 0;
	      }
      else {
        lbr[1] = Math.atan2(car[2],rho)*toDeg;
        lbr[0] = 2.*Math.atan2(car[1],fabs(car[0])+rho)*toDeg;
        if (car[0] < 0.) lbr[0] = 180 - lbr[0];
      else if (car[1] < 0) lbr[0] += 360.;
      }
      return lbr;
     }

     public static double[] pocar (double[] lbr)
     {
      double[] car = new double[3];
      car[0] = lbr[2]*Calculator.cos(lbr[1])*Calculator.cos(lbr[0]);
      car[1] = lbr[2]*Calculator.cos(lbr[1])*Calculator.sin(lbr[0]);
      car[2] = lbr[2]*Calculator.sin(lbr[1]);
      return car;
      }


/** Ekliptikale in aequatoriale Koordinaten umwandeln */
      public static double[] ekq ( double e,
                                   double[] lb )
      {
      double[] rd = new double[2];
      e *= toRad; // Ekliptikschiefe in Bogenmass umrechnen
      rd[1] = Math.asin (Math.sin(e)*Math.cos(lb[1]*toRad)*Math.sin(lb[0]*toRad)
        + Math.cos(e)*Math.sin(lb[1]*toRad))*toDeg;
      rd[0] = Math.atan2( Math.cos(e)*Math.cos(lb[1]*toRad)*Math.sin(lb[0]*toRad)-Math.sin(e)
        * Math.sin(lb[1]*toRad), Math.cos(lb[1]*toRad)*Math.cos(lb[0]*toRad) )*toDeg;
      if (rd[0] < 0) rd[0] += .36e3;
      return rd;
      }

/** Aequatoriale in ekliptikale Koordinaten umrechnen */
      public static double[] qek ( double e, double rd[] )
      {
      double[] lb = new double[2];
      e *= toRad; // Ekliptikschiefe in Radiant umrechnen (lokale Giltigkeit)
      lb[1] = Math.asin (-Math.sin(e)*Math.cos(rd[1]*toRad)*Math.sin(rd[0]*toRad)
        + Math.cos(e)*Math.sin(rd[1]*toRad))*toDeg;
      lb[0] = Math.atan2( Math.cos(e)*Math.cos(rd[1]*toRad)*Math.sin(rd[0]*toRad)+Math.sin(e)
        * Math.sin(rd[1]*toRad), Math.cos(rd[1]*toRad)*Math.cos(rd[0]*toRad) )*toDeg;
      if (lb[0] < 0) lb[0] +=  .36e3;
      return lb;
}

/** Die Längen der zehn astrologischen Planeten errechnen.
    Die Genauigkeit der Methode liegt im Bereich von 1 Bogenminute.
    @param jd Julianisches Datum
    @return Array mit den zehn geozentrischen Planetenlängen. Die
    Reihenfolge entspricht der Reihenfolge der Planeten in der
    globalen Konstante {@link Calculator#pknam Calculator.pknam}
    */
       public static double[] compute (  double jd )
          {
          double planet[] = new double[10];
          double[][] lbr = new double[10][3];
          compute( jd, lbr );
          for ( byte i = 0; i < 10; i++ ) planet[i] = lbr[i][0];
          return planet;
          }

/** Die vollständigen geozentrischen Polarkoordinaten der zehn
    astrologischen Planeten errechnen.
    Die Genauigkeit der Methode liegt im Bereich von 1 Bogenminute.
    @param jd Julianisches Datum
    @param lbr Zweidimensionaler Array mit den Ergebnissen. Der
    erste Index entspricht der Nummer des Planeten in der
    globalen Konstante {@link Calculator#pknam Calculator.pknam}. Der zweite
    Index zählt die drei Polarkoordinaten durch, in der Reihenfolge
    Länge, Breite, Distanz in AE.
    */
       public static void compute( double jd, double[][] lbr) {

       byte i;
       double nut, dist;
       double lbrHelio[],
              lbrEarth[] = {0.,0.,0.},
              elements[] = new double[8];

/* Sonnenkoordinaten */
       lbr[0] = newcomb(jd);

/* Nutationskorrektur (und Lichtlaufzeit) für Sonne */
      nut = nutation(jd);
      lbr[0][0]   += nut - (geometric ? 0 : 20.81/3600.);
      lbrEarth[0]  = fmod(180. + lbr[0][0],360.);
      lbrEarth[1]  = - lbr[0][1];
      lbrEarth[2] = lbr[0][2];

/* Mond (brown macht schon Nutationskorrektur) */
      lbr[1] = brown( jd );

      for (i=2;i<=9;i++) {

     /*   Grosse Halbachse   = elements[0];
          Exzentrizität      = elements[1];
          Bahnneigung        = elements[2];
          Aufst. Knoten      = elements[3];
          Perihellänge       = elements[4];
          Mittlere Anomalie  = elements[5];
          Tagesbewegung      = elements[6];
          Korrekturfaktor r  = elements[7]; */

/* Bahnelemente errechnen                   */
      Elements.get( jd, i, elements );

/* Lichtlaufzeit-Korrektur für Planeten     */
      if (!geometric) {
// 1) Näherungsweisen Abstand berechnen
        dist = Math.sqrt(1+elements[0]*(elements[0]-2*Calculator.cos(elements[4]+elements[5]-lbrEarth[2])));
// 2) Mittlere Anomalie vor Eingang ins Keplerproblem um Lichtlaufzeit verringern
        elements[5] -= elements[6] * dist * cInvers;
        }

/* Keplerproblem lösen */
      lbrHelio = kepler ( elements );

/* Für Jupiter ... Pluto: Korrekturfaktor deltaR */
      if (i >= 5) lbrHelio[2] *= 1 + elements[7]/10000.;

/* Umwandlung in geozentrische  Koordinaten */
/* Aberration inbegriffen */
      lbr[i] = helge(lbrHelio,lbrEarth);

/* Nutation */
      lbr[i][0] += nut;
      }


      }

/** Umrechnung von heliozentrisch auf geozentrisch.
    Alle Positionen sind in <em>Polarkoordinaten</em>
    anzugeben. Diese werden in einem Array in der Form
    { Länge, Breite, Distanz } übergeben.
    <p>Ist das Flag {@link LowPrecCalculator#geometric geometric}
    abgeschaltet (Default), so
    so wird an dieser Stelle auch die Aberration (<em>nicht
    die Lichtlaufzeit</em>) berücksichtigt, wobei näherungsweise die
    mittlere Erdgeschwindigkeit (Naibodbogen) verwendet wird.
    @param lbrHelio Heliozentrische Position des Objekts
    @param lbrEarth Heliozentrische Position der Erde
    @return Geozentrische Position des Objekts
    */
      public static double[] helge (double[] lbrHelio, double[] lbrEarth)
      {
      double h1,h2,h3,a;
      double[] lbrGeo = new double[3];

/* Berechne den kartesischen geozentrischen Positionsvektor (h1,h2,h3) */
      h1 = lbrHelio[2]*Math.cos(lbrHelio[1]*toRad)*Math.cos(lbrHelio[0]*toRad)-lbrEarth[2]*Math.cos(lbrEarth[1]*toRad)*Math.cos(lbrEarth[0]*toRad);
      h2 = lbrHelio[2]*Math.cos(lbrHelio[1]*toRad)*Math.sin(lbrHelio[0]*toRad)-lbrEarth[2]*Math.cos(lbrEarth[1]*toRad)*Math.sin(lbrEarth[0]*toRad);
      h3 = lbrHelio[2]*Math.sin(lbrHelio[1]*toRad) - lbrEarth[2]*Math.sin(lbrEarth[1]*toRad);

/* Aberration */
      lbrGeo[2] = Math.sqrt(h1*h1+h2*h2+h3*h3)  ;
      a = lbrEarth[2] * lbrGeo[2] * naibod * cInvers * toRad;
      if (!geometric) {
       h1 -= Math.sin( lbrEarth[0]*toRad ) * a ;
       h2 += Math.cos( lbrEarth[0]*toRad ) * a ;
       }

/* Cartesisch in Polar umrechnen */
      lbrGeo[0]  = Math.atan2(h2,h1);
      lbrGeo[0]  = fmod(lbrGeo[0],2*Math.PI);
      lbrGeo[1] = Math.atan2(h3,h2/Math.sin(lbrGeo[0]));
      lbrGeo[0] = lbrGeo[0] * toDeg;
      lbrGeo[1] = lbrGeo[1] * toDeg;

      return lbrGeo;

      }

}   // class LowPrecCalculator


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