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

Klasse Horoscope

Javadoc von Horoscope   Horoscope.java herunterladen

package AstroOL;

import AstroOL.Calculator;
import java.util.*;
import java.io.*;
import swisseph.*;

/** Die Klasse Horoskop verwaltet die mit einem Horoskop verbundenen
Informationen und bietet Methoden zum Berechnen, Laden und Speichern
von Horoskopen und aus diesen abgeleiteten Informationen (z.B. einer
Aspekttafel). */
public class Horoscope {

/** Festwert für Zeitbestimmung aus der Länge des Medium Coeli */
  public static final char timeSpecMediumCoeli     = 'm';
/** Festwert für Zeitbestimmung aus der Länge des Aszendenten */
  public static final char timeSpecAscendent       = 'a';
/** Festwert für Zeitbestimmung: Sternzeit */
  public static final char timeSpecSiderealTime    = 's';
/** Festwert für Zeitbestimmung: RAMC */
  public static final char timeSpecRAMC            = 'r';
/** Festwert für Zeitbestimmung: Weltzeit (U.T. oder GMT) */
  public static final char timeSpecUniversalTime   = 'u';
/** Festwert für Zeitbestimmung: Ephemeridenzeit (E.T.)  */
  public static final char timeSpecEphemerisTime   = 'e';
/** Festwert für Zeitbestimmung: Mittlere Ortszeit */
  public static final char timeSpecLocalMeanTime   = 'l';
/** Festwert für Zeitbestimmung: Wahre Ortszeit */
  public static final char timeSpecTrueLocalTime   = 'w';
/** Festwert für Zeitbestimmung: Temporalstunden. Die klassische Zeitrechnung
basierte auf ungleich langen Stunden am Tage und in der Nacht, entsprechend dem
Tag- und Nachtbogen der Sonne. Die Zeitbestimmung gemäß Temporalstunden
ist so geeicht, daß die Uhrzeit 12 Uhr immer dem Sonnenauf- und 0 Uhr dem
Sonnenuntergang entspricht. */
  public static final char timeSpecTemporalHours   = 'h';
/** Festwert für Zeitbestimmung aus der Länge der Sonne (Solarhoroskop).
Es wird ab dem angegebenen Datum nach der Zeit gesucht, zu der die Sonne den
angegebenen Längenwert erreicht. */
  public static final char timeSpecSolarRevolution = 'S';
/** Festwert für Zeitbestimmung aus der Länge des Mondes (Lunarhoroskop).
Es wird ab dem angegebenen Datum nach der Zeit gesucht, zu der der Mond den
angegebenen Längenwert erreicht. */
  public static final char timeSpecLunarRevolution = 'L';
/** Festwert für Zeitbestimmung aus dem letzten Erreichen der angegebenen
Mondphase */
  public static final char timeSpecLunarReturn      = 'P';

/** Festwert für sensitive Punkte: Starke Aspekte.  */
  public static long sensPtAspStrong = 1l;
/** Festwert für sensitive Punkte: Mittlere Aspekte.  */
  public static long sensPtAspMedium = 2l;
/** Festwert für sensitive Punkte: Schwache Aspekte.  */
  public static long sensPtAspWeak   = 4l;
/** Festwert für sensitive Punkte: Alle Aspekte. Dieser Festwert
ist nichts anderes als das Bit-Oder der Festwerte für starke,
schwache und mittlere Aspekte. */
  public static long sensPtAsp       = 7l;
/** Festwert für sensitive Punkte: Halbdistanzpunkte.  */
  public static long sensPtHdp       = 8l;
/** Festwert für sensitive Punkte: Antiszien.  */
  public static long sensPtAzm       = 16l;
/** Festwert für sensitive Punkte: Alles. Es werden alle
Arten von sensitiven Punkten berücksichtigt. */
  public static long sensPtAll       = 31l;

  public static final int houseRange = 1000;
/** Array der dreibuchstabiger Kurztexte für die Häuserspitzen */
  public static final String[] houseTextShort =
    { "ASC", "II", "III", "IC", "V", "VI", "DSC", "VIII", "IX", "MC", "XI", "XII" } ;
/** Array der zweibuchstabiger Kurztexte für die Planeten in der Reihenfolge
SO, MO, ME, ... PL */
  public static final String[] planetTextShort =
    { "SO", "MO", "ME", "VE", "MA", "JU", "SA", "UR", "NE", "PL" };
/** Planetennamen */
  public static final String[] planet =  { "Sonne","Mond","Merkur",
                                           "Venus", "Mars","Jupiter",
                                           "Saturn","Uranus","Neptun",
                                           "Pluto" },
/** Namen der Tierkreiszeichen */
                               sign = {"Widder","Stier","Zwillinge",
                                       "Krebs","Loewe","Jungfrau",
                                       "Waage","Skorpion","Schuetze",
                                       "Steinbock","Wassermann","Fische"};

  public static final double[] aspect  = { 0d, 30d, 45d, 60d, 90d, 120d, 135d, 150d, 180d };
/** Boolescher Array der schwachen Aspekte (Halbsextil und Quincunx) */
  public static final boolean[] isWeak = {false, true, false, false, false, false, false, true, false };
/** Boolescher Array der mittleren Aspekte ( Halbquadrat, Sextil, Trigon, Anderhalbquadrat ) */
  public static final boolean[] isMedium = { false,false,true,true,
                                             false,true,true,false,false};
/** Boolescher Array der starken Aspekte ( Konjunktion, Quadrat, Opposition ) */
  public static final boolean[] isStrong = { true, false, false, false,
                                         true, false, false, false, true };

/** Array der dreibuchstabiger Kurztexte für die Aspekte */
  public static final String[] aspectTextShort =
    { "CON","SSX","SSQ","SXT","SQU","TRI","SQQ","QCX","OPP" };

/** Aspekte: Index der Konjunktion */
  public static final int con = 0;
/** Aspekte: Index des Halbsextils */
  public static final int ssx = 1;
/** Aspekte: Index des Halbquadrats */
  public static final int ssq = 2;
/** Aspekte: Index des Sextils */
  public static final int sxt = 3;
/** Aspekte: Index des Quadrats */
  public static final int squ = 4;
/** Aspekte: Index des Trigons */
  public static final int tri = 5;
/** Aspekte: Index des Anderthalbquadrats */
  public static final int sqq = 6;
/** Aspekte: Index des Quincunx */
  public static final int qcx = 7;
/** Aspekte: Index der Opposition */
  public static final int opp = 8;


/** Schlüssel für Halbdistanzpunkte */
  public static final int hdp = 100;

/** Schlüssel für Antiszien */
  public static final int azm = 200;
/** Schlüssel für Gegenpunkt von Antiszien */
  public static final int aaz = 201; // Gegenpunkt

/** Schlüssel für freie Aspektstelle */
  public static final int fra = 1000;

/** Schlüssel für freie Ekliptikstelle */
  public static final int frp = 1001;

/** Gesamtzahl der verwendeten Faktoren (Planeten) */
  public static final int maxPlanets = 10;

/** Sternzeit in Grad (= RAMC) */
  public double st;
/** Geographische Koordinaten */
  public double lon, lat;
/** Julianisches Datum in UT */
  public double  jd;
/** Zeitmass */
  public double time;
/** Zeitart (Wahre Zeit, Sommerzeit, etc. ) */
  public char timeSpec;
/** Wahre Ekliptikschiefe des Datums */
  public double ee;
/** Differenz ET-UT in Tagen */
  public double deltaT;
/** Name des Geburtsortes (optional) */
  public String location;
/** Name des Horoskops (optional) */
  public String name;
/** Kurzname des Horoskops (zum Sichern etc.) */
  public String nameShort;
/** Kommentar */
  public String comment;
/** Längen, Breiten, tägliche Bewegungen der Planeten */
  public double[] pl,pb,dm;
/** Häuserspitzen, besondere trig. Punkte */
  public double[] houses = new double[13], ascmc = new double[10];
/** Symbolisches Horoskop */
  public boolean symbolic = false;

/** Aspekttafel - wird auf Anforderung aufgebaut */
  ArrayList aspectarium;
/** Filterwert zum aktuellen Aspektarium - welche Aspekte sind
    in die Liste aufzunehmen? */
  long aspectariumFilter = 0;

/** Indextabelle für Planeten: Um die Planeten Nr. 3, 17 und 22
    in einem Array der Länge 3 abzulegen.
    Wird zur Zeit nicht benötigt, da die Nummern 0 bis 9 der Swiss
    Ephemeris (SO, MO, ME, ... PL) genau die benötigten Horoskopsymbole
    sind.  */
  private int[] tabix;

/** Häusersystem */
  private int hsys = Mundan.PLACIDUS;

/** Funktionen der Swiss Library */
  private static SwissLib sl;
  public static SwissLib sl() {
    if (sl == null) sl = new SwissLib();
    return sl;
    }
  private static SwissEph se;
  public static SwissEph se() {
    if (se == null) se = new SwissEph("C:\\Sweph\\ephe");
    return se;
    }
  private static SweDate sd;
  public static SweDate sd() {
    if (sd == null) sd = new SweDate();
    return sd;
    }

/** Testmethode */
  public static void main(String[] args) {
    double[] tt = new double[3];
    tt[0] = SweDate.getJulDay(1954,2,19,22.5,SweDate.SE_GREG_CAL);;
    Horoscope h = new Horoscope( tt[0], 7.2833, 52.3333);
    System.out.println(h);
    System.out.println(aufgang(tt,SweConst.SE_SUN, 7.2833, 52.3333));
    h = new Horoscope( tt[0]-sd().getDeltaT(tt[0]), 7.2833, 52.3333);
    System.out.println( h );
    }

  public Horoscope() {};

/** Konstruktor für symbolische Horoskope */
  public Horoscope(double[] planets, double[] houses) {
    this.pl       = planets;
    this.houses   = houses;
    this.symbolic = true;
    }

/** Horoskop aus seinen Minimal-Angaben konstruieren */
  public Horoscope(double jd_ut, double lon, double lat, int hsys) {
    setAttributes( jd_ut, lon, lat, hsys);
    }

/** Horoskop aus Ort und Zeit konstruieren, verschiedene Arten der Zeitangabe sind möglich. */
  public Horoscope(double jd0, double lon, double lat, double time, char timeSpec, int hsys) {
    double[] tt = new double[3];
    tt[0] = jd0;
    zeitbest(tt, lon, lat, time, timeSpec);
    setAttributes(tt[0]-sd().getDeltaT(tt[0]), lon, lat, hsys);
    }

/** Horoskop aus seinen Minimal-Angaben konstruieren. Es wird das Default-Häusersystem
    (Placidus) verwendet */
  public Horoscope(double jd_ut, double lon, double lat) {
    this(jd_ut,lon,lat,(int) Mundan.PLACIDUS );
    }

/** In allen Konstruktoren (ausser dem symbolischen) durchlaufenes Coding */
  private void setAttributes(double jd_ut, double lon, double lat, int hsys) {
    double[] xx = new double[6];
    StringBuffer serr = new StringBuffer();
    this.jd  = jd_ut;
    this.lon = lon;
    this.lat = lat;
    time = (jd-.5d-Math.floor(jd-.5d))*24;
    timeSpec = timeSpecUniversalTime;
    tabix = new int[10] ;
    pl = new double[10] ;
    pb = new double[10] ;
    dm = new double[10] ;
    deltaT = SweDate.getDeltaT(jd);
    for (int i=0; i<10;i++) {
      se().swe_calc(jd+deltaT,i,SweConst.SEFLG_SPEED,xx,serr);
      pl[i] = xx[0];
      pb[i] = xx[1];
      dm[i] = xx[3];
      tabix[i] = i;
      }
    se().swe_calc(jd+deltaT,SweConst.SE_ECL_NUT,0,xx,serr);
    ee = xx[0];
    se().swe_houses(jd,0,lat,lon,hsys,houses,ascmc);
    st = 15 * sl().swe_sidtime( jd ) + lon;
    }

/** Planet oder Haus mit der Nummer i zurückgeben */
  public double pl( int i ) {
    if (i < houseRange) return pl[i];
    else return houses[ i - houseRange ];
    }
  public double pb( int i ) {
    if (i < houseRange) return pb[i];
    else return 0d;
    }
  public double dm( int i ) {
    if (i<houseRange)return dm[i];
    else return 0d;
    }

  public double h( int i ) {
    return houses[i];
    }

  public static String planetTextShort( int i ) {
    if (i <= houseRange) return planetTextShort[i];
    else return houseTextShort[i-houseRange-1];
    }

  public byte hsys() { return (byte) hsys; }

  public ArrayList aspectarium() {
    return aspectarium( sensPtAll );
    }

  public ArrayList aspectarium(long filter) {

    if (aspectarium == null) aspectarium = new ArrayList();

// Passt der aktuelle Filter? Dann kann Aspekttafel zurückgegeben werden
    if (filter == aspectariumFilter) return aspectarium;

// Es müssen die neu hinzukommenden Aspekte eingefügt werden
    if ((filter & ~aspectariumFilter) != 0) {
      addAspects( filter & ~aspectariumFilter );
       }

// Die nicht mehr gewünschten Komponenten müssen entfernt werden
    if ((~filter & aspectariumFilter) != 0) {

      subtractAspects( ~filter & aspectariumFilter );

      }

    aspectariumFilter = filter;
    return aspectarium;
    }

/** Hinzufügen der durch Filter gegebenen Objekte zur Liste */
    private void addAspects(long filter) {

      int i,j,k,s;
      AspectPoint a;

// 1.) Aspekte der Planeten
      if ((filter & sensPtAsp) != 0)
      for (i = 0; i < maxPlanets; i++)
        for (j = 0; j < aspect.length; j++) {
          if (( (filter & sensPtAspWeak) == 0) && isWeak[j] ) continue;
          if (( (filter & sensPtAspMedium) == 0) && isMedium[j] ) continue;
          if (( (filter & sensPtAspStrong) == 0) && isStrong[j] ) continue;
          for (s = -1; s <= 1 ; s+=2) {
            // Konjunktion und Opposition werden nur positiv gerechnet
            if ( (s==-1) && ((j == 0) || (j == aspect.length-1))) continue;
            a = new AspectPoint();
            a.aspect  = j;
            a.aspectSign = (s > 0) ? '+' : '-';
            a.planet1 = i;
            a.planet2 = -1;
            a.lon     = Calculator.fmod360(pl(i)+s*aspect[j]);
            k = Collections.binarySearch(aspectarium, a);
            if (k < 0) aspectarium.add(-k-1,a);
            }
          }

// 1a) Häuserspitzen sowie Aspekte zu den Achsen
      for (i = 1; i<=12; i++) {
        if (((i==1)||(i==10))&&((filter & sensPtAsp)!=0)) {
          for (j = 0; j < aspect.length; j++) {
            if (( (filter & sensPtAspWeak) == 0) && isWeak[j] ) continue;
            if (( (filter & sensPtAspMedium) == 0) && isMedium[j] ) continue;
            if (( (filter & sensPtAspStrong) == 0) && isStrong[j] ) continue;
            for (s = -1; s <=1; s+=2) {
              if ( (s==1) && ((j == 0) || (j == aspect.length-1))) continue;
              a = new AspectPoint();
              a.aspect  = j;
              a.planet1 = houseRange + i;
              a.planet2 = -1;
              a.lon     = Calculator.fmod360(h(i)+s*aspect[j]);
              k = Collections.binarySearch(aspectarium, a);
              if (k < 0) aspectarium.add(-k-1,a);
              }
            }
          }
// Wenn nur starke Aspekte gewünscht sind: Keine Zwischenhäuser
        else if ((filter & sensPtAsp) != sensPtAspStrong)  {
              a = new AspectPoint();
              a.aspect  = 0;
              a.planet1 = houseRange + i;
              a.planet2 = -1;
              a.lon     = Calculator.fmod360(h(i));
              k = Collections.binarySearch(aspectarium, a);
              if (k < 0) aspectarium.add(-k-1,a);
              }
        }

// 2.) Alle Halbsummen
      if ((filter & sensPtHdp) != 0)
      for (i = 0; i < maxPlanets; i++)
        for (j = 0; j < maxPlanets; j++)
          for (s = 0; s <=180; s+=180) {
            a = new AspectPoint();
            a.aspect  = hdp;
            a.planet1 = i;
            a.planet2 = j;
            a.lon     = Calculator.fmod360((pl(i)+pl(j))/2+s);
            k = Collections.binarySearch(aspectarium, a);
            if (k < 0) aspectarium.add(-k-1,a);
            }

// 3.) Alle Antiszien
      if ((filter & sensPtAzm) != 0)
      for (i = 0; i < maxPlanets; i++)
          for (s = 0; s <=180; s+=180) {
            a = new AspectPoint();
            if (s==0) a.aspect  = azm;
            else a.aspect = aaz;
            a.planet1 = i;
            a.planet2 = -1;
            a.lon     = Calculator.fmod360(180d-pl(i)+s);
            k = Collections.binarySearch(aspectarium, a);
            if (k < 0) aspectarium.add(-k-1,a);
            }
  }

/** Entfernen der durch filter gegebenen Objekte aus der Liste */
  private void subtractAspects( long filter ) {

  ListIterator aIt = aspectarium.listIterator();
  while (aIt.hasNext()) {
    AspectPoint a = (AspectPoint) aIt.next();
    if ((a.aspect == hdp) && ( (filter & sensPtHdp) != 0) ){
      aIt.remove();
      continue;
      }
    if ((a.aspect == azm) && ( (filter & sensPtAzm) != 0)) {
      aIt.remove();
      continue;
      }
    if ((a.aspect >= 0) && (a.aspect < aspect.length) && ( (filter & sensPtAsp) != 0) ){
      if (isWeak[a.aspect] & ( (filter & sensPtAspWeak) != 0) ) {
        aIt.remove();
        continue;
        }
      if (isMedium[a.aspect] & ( (filter & sensPtAspMedium) != 0) ) {
        aIt.remove();
        continue;
        }
      if (isStrong[a.aspect] & ( (filter & sensPtAspStrong) != 0) ) {
        aIt.remove();
        continue;
        }
      }
    }
  }

/** Liefert eine Liste aller Kontakte mit sensitiven Ekliptikpunkten,
    die auf dem Intervall [l1,l2] auftreten */
  public ArrayList getTransits(double l1, double l2) {
    return getTransits(l1,l2,sensPtAll);
    }

/** Liefert eine Liste aller Kontakte mit sensitiven Ekliptikpunkten,
    die auf dem Intervall [l1,l2] auftreten */
  public ArrayList getTransits(double l1, double l2, long filter) {
    ArrayList list;
    l1 = Calculator.fmod360(l1);
    if (l2 != 360d) l2 = Calculator.fmod360(l2);
    if (l1 > l2) { list = getTransits(0d,l2,filter);
                   list.addAll(getTransits(l1,360d,filter));
                   return list;
                   }
    list = new ArrayList();
    ArrayList a = aspectarium(filter);
    AspectPoint ap1 = new AspectPoint(l1), ap2 = new AspectPoint(l2);
    int i1 = Collections.binarySearch(a,ap1);
    if (i1 < 0) i1 = -i1 - 1;
    int i2 = Collections.binarySearch(a,ap2);
    if (i2 < 0) i2 = -i2 - 1;
    for (int i = i1; i < i2; i++) list.add(a.get(i));
    return list;
    }

    public static void printAspectarium(ArrayList al, PrintStream p) {
      Iterator iter = al.iterator();
      while (iter.hasNext()) {
        AspectPoint a = (AspectPoint) iter.next();
        p.print(Calculator.dms(a.lon,Calculator.ECL+Calculator.SEC)+"\t");
        if (a.planet2 >= 0)
          p.print(planetTextShort(a.planet1)+"/"+planetTextShort(a.planet2));
        else if (a.aspect < 100)
          p.print(aspectTextShort[a.aspect]+" "+planetTextShort(a.planet1));
        else
          p.print("AZM "+planetTextShort(a.planet1));
        p.println();
        }
      }

      public void setName(String name) {
        this.name = name;
        }

      public void setNameShort(String nameShort) {
        this.nameShort = nameShort;
        }

      public void setComment(String comment) {
        this.comment = comment;
        }

/** Kurzname zurückgeben oder aus Langname ableiten */
  public String shortName() {
    if (nameShort.length() > 0) return nameShort;
    else {
      char c;
      StringBuffer x = new StringBuffer();
      for (int i=0; (i < name.length()) && (i < 15); i++)
        if (Character.isJavaIdentifierPart(c = name.charAt(i))) x.append(Character.toLowerCase(c));
        if (x.length() > 0) return x.toString();
      }
      return null;
    }



/** Output des Horoskops als ini Datei auf die Datenbank */
  public void save() throws java.io.IOException {
    if (shortName() != null) save( nameShort + ".dat" );
    else save( "horoscope.dat" );
    }

  public void save(String fileName) throws java.io.IOException {
    Properties horoOut = new Properties();
    horoOut.put("jd",Double.toString(jd));
    horoOut.put("time",Double.toString(time));
    horoOut.put("st",Double.toString(st));
    horoOut.put("timeSpec",""+timeSpec);
    horoOut.put("ee",Double.toString(ee));
    horoOut.put("lon",Double.toString(lon));
    horoOut.put("lat",Double.toString(lat));
    horoOut.put("deltaT",Double.toString(deltaT));
    horoOut.put("pl",Calculator.doubleList(pl));
    horoOut.put("pb",Calculator.doubleList(pb));
    horoOut.put("dm",Calculator.doubleList(dm));
    horoOut.put("houses",Calculator.doubleList(houses));
    horoOut.put("hsys",""+(char)hsys);
    horoOut.put("symbolic",Boolean.toString(symbolic));
    if (comment != null) horoOut.put("comment",comment);
    if (name != null) horoOut.put("name",name);
    if (nameShort == null) nameShort = shortName();
    if (nameShort != null) horoOut.put("nameShort", nameShort);
    if (location != null) horoOut.put("location",location);
    horoOut.store(new FileOutputStream(fileName), name);
    }

/** Horoskop einlesen */
  public static Horoscope load(String fileName) throws java.io.IOException {
    int i;
    Properties horoIn = new Properties();
    if ((i = fileName.indexOf('.')) <= 0) fileName += ".dat";
    horoIn.load( new FileInputStream(fileName) );
    Horoscope h = new Horoscope();
    h.jd = Double.parseDouble(horoIn.getProperty("jd"));
    h.time = Double.parseDouble(horoIn.getProperty("time"));
    h.timeSpec = horoIn.getProperty("timeSpec").charAt(0);
    h.st = Double.parseDouble(horoIn.getProperty("st"));
    h.ee = Double.parseDouble(horoIn.getProperty("ee"));
    h.lon = Double.parseDouble(horoIn.getProperty("lon"));
    h.lat = Double.parseDouble(horoIn.getProperty("lat"));
    h.deltaT = Double.parseDouble(horoIn.getProperty("deltaT"));
    h.houses = new double[13];
    Calculator.parseDoubleList(horoIn.getProperty("houses"),h.houses);
    h.hsys = horoIn.getProperty("hsys").charAt(0);
    h.pl = new double[10];
    Calculator.parseDoubleList(horoIn.getProperty("pl"),h.pl);
    h.pb = new double[10];
    Calculator.parseDoubleList(horoIn.getProperty("pb"),h.pb);
    h.dm = new double[10];
    Calculator.parseDoubleList(horoIn.getProperty("dm"),h.dm);
    h.symbolic = Boolean.valueOf(horoIn.getProperty("symbolic")).booleanValue();
    h.comment = horoIn.getProperty("comment");
    h.name = horoIn.getProperty("name");
    h.nameShort = horoIn.getProperty("nameShort");
    h.location = horoIn.getProperty("location");
    return h;
    }

/** Zeitberechnung für verschiedene Zeitangaben.
    @param time Ein double[3] mit den Werten
      time[0] = Julianisches Datum in ET (dieser Wert ist zu übergeben)
      time[1] = Weltzeit (Ergebnis der Rechnung)
      time[2] = Sternzeit (Ergebnis der Rechnung)
    @param specifier Ein Charakter, der die Zeitangabe bestimmt:
     <pre>
     'e' Ephemeris Time  (Default)
     'w' True Local Time
     'l' Local Mean Time
     't' Temporal Hour
     'u' Universal Time
     's' Sidereal Time in Hours
     'r' Sidereal Time in Degrees (=RAMC)
     'a' Ascendent Longitude
     'm' Medium Coeli Longitude
     'S' Solar Revolution
     'L' Lunar Revolution
     </pre>
      */
public static boolean zeitbest( double[] time,
                              double lon,
                              double lat,
                              double x,
                              char specifier) {
double jd,jd0,jd1,jd2,ut,st;
double b,et,dt,y,z,l,r,v,jd12;
double ecl;
int flag = 0, i,count;
double[] xx = new double[6], tt = new double[3];
StringBuffer serr = new StringBuffer();


jd = time[0];
jd12=Math.floor(jd-.5)+.5; /* Jul. Datum um 0 Uhr UT */
et=(jd-jd12)*24.;
dt = sd().getDeltaT(jd);
st=15*sl().swe_sidtime(jd12)+lon;
se().swe_calc(jd,SweConst.SE_ECL_NUT, 0, xx, serr);
ecl = xx[0];

// Ein Objekt für sphärische Berechnungen
Mundan m = new Mundan(0., lat, ecl, Mundan.PLACIDUS);

switch (specifier) {

case timeSpecMediumCoeli:
  x = m.ramc(x)/15.; /*  LST aus MC-Laenge */
case timeSpecSiderealTime:
  x = 15.*x;  /* Sternzeit in Stunden */
case timeSpecRAMC:   /* Sternzeit in Grad = RAMC: hier einsteigen */
  ut = Calculator.fmod((x-st)/15d,24.)/Direct.ST_UT;  /* ut */
  et = ut + dt*24;
  break;

case timeSpecAscendent:
  y = Calculator.fmod(m.oaasc(x)/15d-6d,24.); /* RAMC */
  ut = Calculator.fmod(y-st/15,24.)/Direct.ST_UT; /* ut */
  et = ut + dt*24;
  break;

case timeSpecUniversalTime:  /* Greenwich Mean Time (= Universal Time) */
  ut = x;
  et = ut + dt*24;
  break;

case timeSpecLocalMeanTime: /* Mittlere Ortszeit */
  ut = x - lon/15.;
  et = ut + dt*24;
  break;

case timeSpecTrueLocalTime:  /* Wahre Ortszeit */
  for (i=0;i<=5;i++) {
    se().swe_calc(jd,SweConst.SE_SUN,flag,xx,serr);
    y = m.ramc(xx[0]);
    z = Calculator.fmod360(y + x*15. - 180.);
    st=15.*sl().swe_sidtime(jd-dt)+lon;
    if (i==0)
      b = Calculator.fmod360(z-st)/360./Direct.ST_UT;
    else
      b = Calculator.arcdiff(z,st)/360./Direct.ST_UT;
    jd += b;
    et=(jd-.5-Math.floor(jd-.5))*24.;
    }
    ut = et - dt*24;
    break;

case timeSpecSolarRevolution:   /* Solar Revolution */

  /* Das zum angegebenen Datum gültige Solar */
    se().swe_calc(jd12,SweConst.SE_SUN,flag,xx,serr);


  /* 1. Ungefähres Erreichen der Sonnenlänge */
  y = jd - Calculator.fmod360(xx[0]-x)/Direct.naibod;

  for(i=0; (Calculator.arcdiffAbs(xx[0],x) > Mundan.SPREC) && (i<Mundan.MAXIT); i++) {
      se().swe_calc(y,SweConst.SE_SUN,SweConst.SEFLG_SPEED,xx,serr);
      y -= Calculator.arcdiff(xx[0],x)/xx[3];
      }


  if (i==Mundan.MAXIT) {
//      System.out.println("Genauigkeitsfehler bei Solarberechnung!\n");
//      System.out.println("Letzter Längenwert: %s\n",Calculator.dms(l));
      return false;
      }

  jd12=Math.floor(y-.5)+.5; /* Jul. Datum um 0 Uhr UT */
  et=(y-jd12)*24.;
  ut = et - dt*24;
  break;

case timeSpecTemporalHours: /* Temporal */
  /* 0 Uhr = Sonnenuntergang, 12 Uhr = Sonnenaufgang */

  /* Berechne den naechsten Sonnenuntergang     */
  tt = new double[2];
  tt[0] = jd;
  tt[1] = et;
  if (!aufgang(tt,SweConst.SE_SUN,Calculator.arcdiff(lon+180.,0d),-lat)) return false;
  jd0 = tt[0]; // ET

  /* Berechne den darauffolgenden Sonnenaufgang */
  if (!aufgang(tt,SweConst.SE_SUN,lon,lat)) return false;
  jd1 = tt[0]; // ET

  /* Berechne den darauffolgenden Sonnenuntergang */
  if (!aufgang(tt,SweConst.SE_SUN,Calculator.arcdiff(lon+180.,0d),-lat)) return false;
  jd2 = tt[0]; // ET

  /* Tag- oder Nachtzeit */
  if (x<12)
    jd = x/12.*(jd1-jd0)+jd0;
  else
    jd = (x-12.)/12.*(jd2-jd1)+jd1;

  jd12=Math.floor(jd-.5)+.5; /* Jul. Datum um 0 Uhr UT */
  et=(jd-jd12)*24.;
  ut = et - 24*dt;
  st=15.*sl().swe_sidtime(jd-dt)+lon;
  break;

case timeSpecLunarRevolution:  /* Letztes Erreichen der angegebenen Mondlon */

  /* 1. Ungefaehres Erreichen */
  count = 0;
  y = jd-Direct.tropicalLunation;
  se().swe_calc(y,SweConst.SE_MOON,0,xx,serr);
  y += Calculator.fmod360(x-xx[0])/360.*Direct.tropicalLunation;
  se().swe_calc(y,SweConst.SE_MOON,SweConst.SEFLG_SPEED,xx,serr);

  /* 2. Genaues Erreichen */
  for(i=0; (Calculator.arcdiffAbs(xx[0],x) > Mundan.SPREC) && (i<Mundan.MAXIT); i++) {
      y += Calculator.arcdiff(x,xx[0])/xx[3];
      se().swe_calc(y,SweConst.SE_MOON,SweConst.SEFLG_SPEED,xx,serr);
      }

  if (i==Mundan.MAXIT) {
     return false;
     }

  jd12=Math.floor(y-.5)+.5; /* Jul. Datum um 0 Uhr UT */
  et=(y-jd12)*24.;
  ut = et - dt*24;
  break;


case timeSpecLunarReturn:  /* Letztes Erreichen der angegebenen Mondphase */
  i = 0;
  y = jd;
  do {
    if (++i == Mundan.MAXIT ) return false;
    se().swe_calc(y,SweConst.SE_MOON,SweConst.SEFLG_SPEED,xx,serr);
    l = xx[0];
    v = xx[3];
    se().swe_calc(y,SweConst.SE_SUN,SweConst.SEFLG_SPEED,xx,serr);
    if (i==1) l = Calculator.fmod360(l-xx[0]-x);
    else l = Calculator.arcdiff(l,xx[0]-x);
    v = v-xx[3];
    y -= l/v;
    } while (Calculator.fabs(l) > Mundan.SPREC);

  jd12=Math.floor(y-.5)+.5; /* Jul. Datum um 0 Uhr UT */
  et=(y-jd12)*24.;
  ut = et - dt*24;
  break;

default:
  et = x;  /* Default ist ET  */
  ut = et - dt*24; /* Weltzeit */

} /* Ende von SWITCH */


/* Für späteren Gebrauch */
jd = jd12 + et/24.;

st=15.*sl().swe_sidtime(jd-dt)+lon;

time[0] = jd;
time[1] = et;
time[2] = st;

return true;
}

// Hilfskonstante für die formatierte Ausgabe der Planetennamen in Methode toString()
private static final String sep = ":            ";
/* Horoskop im Plain-Text Format ausgeben */
public String toString() {
        double jd12=Math.floor(jd-.5)+.5; /* Jul. Datum um 0 Uhr UT */
        double ut=(jd-jd12)*24.;
        StringBuffer s = new StringBuffer();
        if (!symbolic) {
          s.append("Julianisches Datum:    " + Double.toString(jd) + "\n");
          s.append("Kalenderdatum:         " + Calculator.date(jd) + "\n");
          s.append("Weltzeit:              " + Calculator.dms(ut,Calculator.TIME+Calculator.SEC) + "\n");
          s.append("Sternzeit (RAMC)       " + Calculator.dms(st,Calculator.GEO+Calculator.SEC) + "\n");
          s.append("Geographische Länge:   " + Calculator.dms(lon,Calculator.LONG+Calculator.SEC) + "\n");
          s.append("Geographische Breite:  " + Calculator.dms(lat,Calculator.LAT+Calculator.SEC) + "\n");
          }
        s.append("Aszendent:             " + Calculator.dms(h(1),Calculator.ECL+Calculator.SEC) + "\n");
        s.append("Medium Coeli:          " + Calculator.dms(h(10),Calculator.ECL+Calculator.SEC) + "\n");
        s.append("Haus 2:                " + Calculator.dms(h(2),Calculator.ECL) + "\n");
        s.append("Haus 3:                " + Calculator.dms(h(3),Calculator.ECL) + "\n");
        s.append("Haus 11:               " + Calculator.dms(h(11),Calculator.ECL) + "\n");
        s.append("Haus 12:               " + Calculator.dms(h(12),Calculator.ECL) + "\n");
        for ( int i = 0; i < 10; i++ )
          s.append(planet[i] + sep.substring(0,12-planet[i].length()) + Calculator.dms(pl[i],Calculator.ECL+Calculator.SEC) + "\n");
        return s.toString();
  }

/* Berechne ET des naechsten Aufgangs des Planeten planet */
public static boolean aufgang(double[] tt,int planet, double lon, double lat)
{
double xjd, xjd12, st, lst0,et0,et1,dt,l,b,r,alngspeed,a,d,y, ecl;
double[] coor = new double[3];
double[] xx = new double[6];
int flag = 0, zahl = 0;
StringBuffer serr = new StringBuffer();

xjd = tt[0];
dt  = sd().getDeltaT(xjd)*24.;                  /* Delta T in Stunden     */
xjd12 = Math.floor(xjd-0.5)+0.5;                /* Jul. Datum um 0 Uhr ET */
tt[1] = et0  = (xjd-xjd12)*24.; /* Angegebene Zeit        */
lst0 = 15*sl().swe_sidtime(tt[0]-dt/24)+lon;   /* Ortssternzeit (RAMC) zum ang. Datum */
se().swe_calc( xjd, SweConst.SE_ECL_NUT, 0, xx, serr);
ecl = xx[0]; // Wahre Ekliptikschiefe (= inklusive Nutation)

do {
  et1 = tt[1];                                       /* Letzte ET merken */
  se().swe_calc(xjd12+tt[1]/24,planet,flag,xx,serr);
/* Umwandlung der ekliptikalen in aequatoriale Koordinaten */
  sl().swe_cotrans( xx,0,coor,0,-ecl);
/* Wenn man in den zirkumpolaren Bereich gelangt: Aufhören */
  if (Calculator.fabs(coor[1])+Calculator.fabs(lat)>90.) return false;
/* Schräge Aufsteigung aus RA, Deklination und geogr. Breite */
  y = Calculator.fmod360(Mundan.oa(coor[0],coor[1],lat)-90.);  /* OA-90 -> RAMC */
  tt[1] = Calculator.fmod360(y-lst0)/Direct.ST_UT/15. + et0;  /* in den 24 Std. nach ET0 */
  zahl ++;
  } while
      (((Calculator.arcdiffAbs(tt[1]*15,et1*15)/15d)>Mundan.SPREC) && (zahl<Mundan.MAXIT));

if (zahl == Mundan.MAXIT)  return false;

tt[0] = xjd12 + tt[1]/24.;   /* JD in ET zurückgeben */
tt[1] = Calculator.fmod(tt[1],24d);
return true;

}

/** Letzte Syzygie (Voll- oder Neumond) vor dem angegebenen julianischen Datum
berechnen
@param jd Julianisches Datum (ET). Es wird der letzte Neu- oder Vollmond vor diesem Datum
berechnet.
@return Julianisches Datum (ET) der Syzygie */
public static double lastSyzygy( double jd ) {

  double x;
  double[] xx = new double[6], tt = new double[3];
  StringBuffer serr = new StringBuffer();

  se().swe_calc(jd,SweConst.SE_MOON,SweConst.SEFLG_SPEED,xx,serr);
  x = xx[0];
  se().swe_calc(jd,SweConst.SE_SUN,SweConst.SEFLG_SPEED,xx,serr);
  x -= xx[0];
  tt[0] = jd;
  if (Calculator.fmod360(x)>180)
    zeitbest(tt,0d,0d,180d,timeSpecLunarReturn);
  else
    zeitbest(tt,0d,0d,0d,timeSpecLunarReturn);
  return tt[0];
  }


/** Ermittle den Index eines Planeten im Array
    -1 wenn Planet (noch?) nicht im Array abgelegt */
  private int ix( int i ) {
    int index;
    if (i >= tabix.length) return -1;
    else return tabix[i];
    }

}






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