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

Klasse Direct

Javadoc von Direct   Direct.java herunterladen source file
package AstroOL;

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


/** Berechnung von Primärdirektionen. Primärdirektionen sind ein traditionelles,
auf der Bewegung des <code>primum mobile</code> basierendes Prognoseverfahren. Diese
Klasse löst für die verschiedenen im Umlauf befindlichen Direktionsverfahren und
mundanen Positionsbegriffe jeweils die folgenden Grundfragen;
<ul>
<li>Berechne den Direktionsbogen für eine mit Promissor und Signifikator gegebene
Direktion (Methode {@link #calcdir(double, double, double, double) calcdir()});
<li> Finde die Ereigniszeit, die einem gegebenen Direktionsbogen entspricht und
vice versa (Methoden {@link #dbogen(Horoscope, double, boolean) dbogen()} und
{@link #ezeit(Horoscope, double) ezeit()});
<li> Bilde eine Liste der in einem bestimmten Zeitintervall fälligen Direktionen
(Methode {@link #getDirections(Horoscope, double, double) getDirections()}).
</ul>
Für nähere Einzelheiten sei auf mein Buch "Primärdirektionen - eine Darstellung
ihrer Technik", Mössingen 1996, verwiesen.
<p>
Planetenberechnungen und teilweise auch die mundanen Positionsrechnungen werden
unter Verwendung des Java-Ports der Swiss Ephemeris durchgeführt (der Rechner ist
also hier nicht frei wählbar).
@see <a href="http://www.astrotexte.ch/sources/rppl.html">Lizenzbedingungen</a>
*/

public class Direct {

// Direktionsverfahren
/** Das Standardverfahren. Erläuterung in "Primärdirektionen", Abschnitt 2.1 */
public static final byte STANDARD      = 0;
/** Dirigieren nach schräger Aufsteigung. Erläuterung in "Primärdirektionen", Abschnitt 2.7 */
public static final byte OA            = 1;
/** Dirigieren nach gerader Aufsteigung. Erläuterung in "Primärdirektionen", Abschnitt 2.7 */
public static final byte RA            = 2;
/** Dirigieren nach dem Goldmayer-Verfahren. Erläuterung in "Primärdirektionen", Abschnitt 2.5 */
public static final byte GOLDMAYER     = 3;
/** Topozentrisch. Erläuterung in "Primärdirektionen", Abschnitt 4.4 */
public static final byte TOPO          = 4;
/** Direktionen nach E. C. Kuehr. Erläuterung in "Primärdirektionen", Abschnitt 4.3 */
public static final byte KUEHR         = 5;

// Direktionsschluessel
/** Ptolemäusschlüssel (1 Grad = 1 Jahr). */
public static final byte keyPtolemaeus   = 0;
/** Wahre-Zeit-Schlüssel (RA-Zuwachs der Sonne x Tage nach Geburt = x Jahre). */
public static final byte keyTrueTime     = 1;
/** Naibodschlüssel (0°59'8" = 1 Jahr). */
public static final byte keyNaibod       = 2;
/** Cardanoschlüssel (1 Grad = 1 Jahr + 1/72 Jahr = 1 Jahr + 5 Tage). */
public static final byte keyCardano      = 3;
/** Kündigschlüssel (Umfang des Längengrades der Sonne, gemessen in RA = 1 Jahr). */
public static final byte keyKuendig      = 4;
/** Besslerschlüssel (Fortschritt der Sonnenlänge am Geburtstag = 1 Jahr). */
public static final byte keyBessler      = 5;
/** Schlüssel <code>diei motu</code> (Fortschritt der Sonnen-RA am Geburtstag = 1 Jahr). */
public static final byte keyDieiMotu     = 6;
/** Proportionalschlüssel (RAMC-Fortschritt in 1/3652.2424 Tagen = 1 Jahr) */
public static final byte keyProportional = 7;

// Umlaufzeiten
/** Dauer des tropischen Mondmonats */
public static final double tropicalLunation = 27.321582;
/** Dauer des tropischen Sonnenjahrs */
public static final double tropicalYear     = 365.2424;

/* Deklarationen fuer Direktionsberechnungen */
public static final double degToDay = 2.7379108e-3;
/** Umrechnungsfaktor Sternzeit in Weltzeit */
public static final double ST_UT    = 1.0027379093;
/** Naibod-Faktor (360° / 1 tropisches Jahr) */
public static final double naibod   = 360d/tropicalYear;
/** Cardano-Faktor (cardano Grad = 1 Jahr) */
public static final double cardano   = 72d/73d;
/** Proportionalfaktor (proportional Grad = 1 Jahr) */
public static final double proportional = 360 * (1d+tropicalYear)/tropicalYear/tropicalYear;


/** Direktionsverfahren */
public byte dirsystem = STANDARD;
/** Direktionsschlüssel */
public byte key       = keyPtolemaeus;
/** In Direktionsberechnungen Promissoren mit Breite rechnen */
public boolean promBreite = false;
/** In Direktionsberechnungen Signifikatoren mit Breite rechnen */
public boolean sigBreite  = false;
/** In Listberechnungen nur direkte Direktionen verwenden */
public boolean onlyDirect = false;

protected Mundan m;
protected SwissLib sl;
protected SwissEph se;
protected Horoscope h; // Ein Radixhoroskop

private boolean traceMode = false;
private PrintWriter trc;

/** Leerer Konstruktor. Es wird eine Instanz für Direktionsberechnungen
nach dem Standverfahren mit dem Ptolemäusschlüssel gebildet. */
  public Direct() {
    m = new Mundan();
    sl = new SwissLib();
    initializations();
  }

/** Konstruktor mit Angabe des gewünschten Direktionsverfahrens. */
  public Direct( byte dirsystem ) {
    m = new Mundan();
    sl = new SwissLib();
    this.dirsystem = dirsystem;
    initializations();
    }

/** Konstruktor mit Angabe des gewünschten Direktionsverfahrens und -schlüssels. */
  public Direct( byte dirsystem, byte key ) {
    m = new Mundan();
    sl = new SwissLib();
    this.dirsystem = dirsystem;
    this.key = key;
    initializations();
    }

/** Konstruktor für Direktionsrechnungen nach dem Standardverfahren unter Verwendung
des Ptolemäusschlüssels. Das Horoskop, auf das die Rechnungen anzuwenden sind, wird
gleich mitgegeben. */
  public Direct( Horoscope h ) {
    m = new Mundan(h);
    sl = h.sl();
    this.h = h;
    initializations();
    }

/** Konstruktor für Direktionsrechnungen nach einem wählbaren Direktionsverfahren unter Verwendung
des Ptolemäusschlüssels. Das Horoskop, auf das die Rechnungen anzuwenden sind, wird
gleich mitgegeben. */
  public Direct( Horoscope h, byte dirsystem ) {
    this.dirsystem = dirsystem;
    m = new Mundan(h);
    sl = h.sl();
    this.h = h;
    initializations();
    }

/** Konstruktor für Direktionsrechnungen mit einem wählbaren Direktionsverfahren und -schlüssel.
Das Horoskop, auf das die Rechnungen anzuwenden sind, wird
gleich mitgegeben. */
  public Direct( Horoscope h, byte dirsystem, byte key ) {
    this.dirsystem = dirsystem;
    this.key = key;
    this.h   = h;
    m = new Mundan(h);
    sl = h.sl();
    initializations();
    }


 private void initializations() {
    if (dirsystem == KUEHR) {
      m.setHsys( Mundan.PLACIDUS );
      promBreite = false;
      sigBreite  = true;
      key = keyNaibod;
      }
    if (dirsystem == TOPO)  m.setHsys( Mundan.PLACIDUS );
    if (dirsystem == GOLDMAYER)  m.setHsys( Mundan.REGIOMONTANUS );
   }

/** Häusersystem des Mundanrechners einstellen */
 public void setHsys( byte hsys ) {
   m.setHsys( hsys );
   }

/** Instanz der Swiss Ephemeris, mit der die Planetenberechnungen ausgeführt werden */
 public static SwissEph se() {
    return Horoscope.se();
    }

  public static void main(String[] args) {
    }

/** Direktionsbogen berechnen
    @param ls Ekliptikale Länge des Signifikators
    @param bs Ekliptikale Breite des Signifikators
    @param lp Ekliptikale Länge des Promissors
    @param bp Ekliptikale Breite des Promissors
    @return Direktionsbogen in Grad, mit Vorzeichen (negative Werte stehen für converse Direktionen)
*/
public double calcdir(
double ls, double bs,  /* Koordinaten des Signifikators */
double lp, double bp   /* Koordinaten des Promissors    */
) {

double ra,d,mp,rad, pd,rap,dp;
double[] coor = new double[3];
StringBuffer ambig = new StringBuffer();

if (!promBreite) bp = 0d;
if (!sigBreite) bs = 0d;

if (traceMode) {
  trc.println("L Sig:\t"+Calculator.dms(ls,Calculator.SEC+Calculator.ECL));
  trc.println("B Sig:\t"+Calculator.dms(bs,Calculator.SEC+Calculator.LAT)+"   ");
  trc.println("RA Sig:\t"+Calculator.dms(m.ra(ls,bs))+"   ");
  trc.println("D Sig:\t"+Calculator.dms(m.decl(ls,bs),Calculator.SEC+Calculator.LAT)+"   ");
  trc.println();
  trc.println("L Prom:\t"+Calculator.dms(lp,Calculator.SEC+Calculator.ECL));
  trc.println("B Prom:\t"+Calculator.dms(bp,Calculator.SEC+Calculator.LAT)+"   ");
  trc.println("RA Prom:\t"+Calculator.dms(m.ra(lp,bp))+"   ");
  trc.println("D Prom:\t"+Calculator.dms(m.decl(lp,bp),Calculator.SEC+Calculator.LAT)+"   ");
  trc.println();
  }

switch (dirsystem) {

  case STANDARD:
/* Standardverfahren - Parallelkreis mit mundaner Positionskurve schneiden */
    mp=m.munpos(ls,bs,ambig);
    if (traceMode) trc.println("MP Sig:\t"+Calculator.dms(mp)+"   ");
    rad=m.radir(m.decl(lp,bp),mp);
    if (traceMode) {
      trc.println("RA zu MP Sig und D Prom:\t"+Calculator.dms(rad)+"   ");
      trc.println("DB:\t"+Calculator.dms(Calculator.arcdiff(m.ra(lp,bp),rad))+"   ");
      }
    return Calculator.arcdiff(m.ra(lp,bp),rad);

  case TOPO:
/* Topozentrisch: Parallelkreis mit Grosskreis zur Bodineaux-Polhöhe schneiden */
    mp=m.munpos(ls,bs,ambig);
    if (traceMode) trc.println("MP Sig:\t"+Calculator.dms(mp));
/* Topozentrische Polhöhenformel */
    pd = Calculator.atan( (Calculator.fabs(mp-180.)/90.-1.) * Calculator.tan(m.getLatitude()));
    if (traceMode) trc.println("Polhöhe Sig:\t"+Calculator.dms(pd,Calculator.SEC+Calculator.LAT));
/* Promissor: Umwandlung der ekliptikalen in äquatoriale Koordinaten */
    sl.swe_cotrans( new double[] {lp,bp,1d},0,coor,0,-m.ee());
        
    rad = m.ra(ls,bs) - m.ad( m.decl(ls,bs), pd ) + m.ad(coor[1],pd);
    if (traceMode) {
      trc.println("OA Sig:\t"+Calculator.dms(m.ra(ls,bs) - m.ad( m.decl(ls,bs), pd )));
      trc.println("AD zu PH Sig und D Sig:\t"+Calculator.dms(m.ad(m.decl(ls,bs),pd)));
      trc.println("AD zu PH Sig und D Prom:\t"+Calculator.dms(m.ad(coor[1],pd)));
      trc.println("RA zu MP Sig und D Prom:\t"+Calculator.dms(rad));
      }
    return Calculator.arcdiff(coor[0],rad);

  case KUEHR:
/* Kühr: Parallelkreis mit dem verbindenden Grosskreis von Signifikator und Äquatorpunkt gleicher
   mundaner Position schneiden */
    mp = m.munpos(ls,bs,ambig);
    if (traceMode) trc.println("MP Sig:\t"+Calculator.dms(mp));
    /* Mundane Position des Signifikators nach Placidus bestimmen */

 /* Signifikator: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {ls,bs,1d},0,coor,0,-m.ee());
    d  = coor[1];
    ra = coor[0];
    if (d!=0) pd = -Calculator.atan(Calculator.cos(ra-m.st-mp)/Calculator.tan(d));
/* Für auf dem Äquator liegende Signifikatoren ist kein Kühr-Grosskreis definiert. Wir
   wählen in diesem Fall die Polhöhe des Tangentialkreises der mundanen Positionskurve -
   das ist genau die topozentrische Polhöhe: */
    else pd = Calculator.atan( (Calculator.fabs(mp-180.)/90.-1.) * Calculator.tan(m.getLatitude()));

    if (traceMode) trc.println("PH Sig:\t"+Calculator.dms(pd,Calculator.SEC+Calculator.LAT));

/* Promissor: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {lp,bp,1d},0,coor,0,-m.ee());
    dp = coor[1];
    rap = coor[0];
    rad=Calculator.fmod360(m.st+mp+90+m.ad(dp,pd));
    if (traceMode) trc.println("RA zu PH Sig und D Prom:\t"+Calculator.dms(rad));
    return Calculator.arcdiff(rap,rad);

  case OA:
/* OA-Verfahren: DB = Differenz der OA von Signifikator und Promissor    */
/* Signifikator: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {ls,bs,1d},0,coor,0,-m.ee());
    ra = coor[0];
    d  = coor[1];
/* Promissor: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {lp,bp,1d},0,coor,0,-m.ee());
    rap = coor[0];
    dp  = coor[1];
    if (traceMode) {
      trc.println( "OA Sig:\t"+ Calculator.dms(m.oa(ra,d,m.getLatitude())));
      trc.println( "OA Prom:\t"+ Calculator.dms(m.oa(rap,dp,m.getLatitude())));
      }
    return Calculator.arcdiff(m.oa(rap,dp,m.getLatitude()),m.oa(ra,d,m.getLatitude()));

  case RA:
/* Signifikator: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {ls,bs,1d},0,coor,0,-m.ee());
    ra = coor[0];
    d  = coor[1];
/* Promissor: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {lp,bp,1d},0,coor,0,-m.ee());
    rap = coor[0];
    dp  = coor[1];
    return Calculator.arcdiff(rap,ra);

    case GOLDMAYER:
    if (traceMode) {
      trc.println( "MP Sig:\t"+ Calculator.dms(m.munpos(ls,bs,ambig)));
      trc.println( "MP Prom:\t"+ Calculator.dms(m.munpos(lp,bp,ambig)));
      }
/* Goldmayer: Mundane Positionen von Signifikator und Promissor subtrahieren */
     return Calculator.arcdiff(m.munpos(lp,bp,ambig),m.munpos(ls,bs,ambig));

  default:
    return 0.;
  }

}

/** Berechne die Laenge des Ekliptikpunktes, der als Promissor
zum übergebenen Signifikator genau den übergebenen
Direktionsbogen ergibt
@param bogen Direktionsbogen
@param ls Länge des Signifikators
@param bs Breite des Signifikators
@return Länge der zum Direktionsbogen passenden Promissorstelle */
public double ldirekt(
double bogen,
double ls, double bs
)

{

double rc=0, mp, ra, d, pd;
double[] coor = new double[3];
StringBuffer ambig = new StringBuffer();

/* Mundane Position des Signifikators ermitteln */
mp = m.munpos(ls,bs,ambig);

switch (dirsystem) {

  case STANDARD:
    rc = m.hauslaenge(mp,m.st+bogen);
    break;

  case GOLDMAYER:
    rc = m.hauslaenge(mp+bogen,m.st);
    break;

  case KUEHR:
/* Signifikator: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {ls,bs,1d},0,coor,0,-m.ee());
    ra = coor[0];
    d  = coor[1];
    if (d!=0) {
      pd = -Calculator.atan(Calculator.cos(ra-m.st-mp)/Calculator.tan(d));
      rc = m.aclaenge(Calculator.fmod360(m.st + mp + bogen + 90.),pd);
      }
    else
      rc = m.hauslaenge(mp+bogen);
    break;

  case TOPO:
    pd = Calculator.atan( (Calculator.fabs(mp-180.)/90.-1.)* Calculator.tan(m.getLatitude()));
    rc = m.aclaenge(Calculator.fmod360(m.st + mp + bogen + 90.),pd);
    break;

  case RA:
/* Signifikator: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {ls,bs,1d},0,coor,0,-m.ee());
    coor[0] += bogen;
/* Vorgerückte RA bei gleicher Deklination wieder in ekliptikale Koord. wandeln */
    sl.swe_cotrans( coor,0,coor,0,m.ee());
    rc = coor[0];
    break;

  case OA:
/* Signifikator: Umwandlung der ekliptikalen in aequatoriale Koordinaten */
    sl.swe_cotrans( new double[] {ls,bs,1d},0,coor,0,-m.ee());
    ra = coor[0];
    d  = coor[1];
    rc = m.aclaenge(m.oa(ra,d)+bogen);
    break;
  }

return rc;

}



/** Verwandlung von Ereigniszeit in Bogen.
@param h Zugrundeliegendes Horoskop
@param jd Julianisches Ereignisdatum
@param convers Flag, ob es sich um eine converse Direktion handelt (ergibt
bei gleitenden Schlüsseln wie dem Wahre-Zeit-Schlüssel ein anderes Ergebnis).
@return Direktionsbogen */
public double dbogen(
Horoscope h,
double    jd,  /* Julianisches Ereignisdatum */
boolean   convers
)
{
double l,r,b,tb,x1,x2,d1,d2;
double[] xx, coor;
StringBuffer serr;
int sign = convers?-1:1;

/* Ereignisalter in tropischen Jahren berechnen: */
x1 = (jd-h.jd)/tropicalYear;

switch (key) {

case keyPtolemaeus:
  /* PTOLEMAEUS-Schluessel: 1 Grad = 1 Jahr */
  return x1*sign;

case keyNaibod:
  /* naibod-Schluessel: 0.9856 Grad = 1 Jahr */
  return x1*naibod*sign;

case keyKuendig:
  d1 = Calculator.arcdiff(m.ramc(Math.ceil(h.pl(SweConst.SE_SUN))),
                          m.ramc(Math.floor(h.pl(SweConst.SE_SUN))));
  return d1*x1*sign;


case keyTrueTime:
  /* WAHRE ZEIT: Sonnenfortschritt in RA x Tage nach Geburt = x Jahre */

  if (se == null) se = new SwissEph();
  xx = new double[6];
  coor = new double[3];
  serr = new StringBuffer();

  /* Fuer converse Direktionen Vorzeichen umkehren */
  if (convers) x1 = -x1;

  /* Mit swisseph den Sonnenstand x1 Tage nach der Geburt errechnen -> l */
  se().swe_calc(h.jd+x1,SweConst.SE_SUN, 0,xx,serr);

  /* Progressive Sonnen-RA berechnen und in x1 speichern */
  sl.swe_cotrans( xx,0,coor,0,-m.ee());
  x1 = coor[0];

  /* Radikale Sonnen-RA */
  sl.swe_cotrans( new double[] {h.pl(SweConst.SE_SUN),h.pb(SweConst.SE_SUN),1d},0,coor,0,-m.ee());

  /* Differenzbogen zurueckgeben */
  return Calculator.arcdiff(x1,coor[0]);

case keyDieiMotu:
  /* DIEI MOTU: Sonnenbewegung am Geburtstag in RA = 1 Jahr */

  /* Ereignisalter mit Tagesbewegung Sonne multiplizieren */
  b=x1*h.dm(SweConst.SE_SUN);

  /* Tagesbewegung Sonne von Ekliptik auf Aequator transformieren */
  b*= Calculator.cos(m.ee())/(Math.pow(Calculator.cos(h.pl(SweConst.SE_SUN)),2)
      +Math.pow(Calculator.sin(h.pl(SweConst.SE_SUN))*Calculator.cos(m.ee()),2));

  return b*sign;

case keyCardano:
  return x1*cardano*sign;

case keyProportional:
  return x1*proportional*sign;

case keyBessler:
  /* Sonnenlaenge: Sonnenbewegung am Geburtstag in Laenge = 1 Jahr */
  return x1*h.dm(SweConst.SE_SUN)*sign;

  } /* Switch */

/* Hier kommt er nie hin */
  return 0;
}

/** Verwandlung von Bogen in Ereigniszeit.
@param h Zugrundeliegendes Horoskop
@param x Direktionsbogen
@return Ereigniszeit als Julianisches Datum, zu dem die Direktion sich auslöst.
*/
public double ezeit(
Horoscope h,
double x)

{
double l,r,b,tb,x0,x1,x2,d1,d2;
double[] xx, coor;
StringBuffer serr;
int i;

if (traceMode) {
  trc.println("Geburtsdatum:\t"+Calculator.date(h.jd));
  trc.println("=Julianisches Datum:\t"+(Math.round(10*h.jd)/10d));
  trc.println("Direktionsbogen:\t"+Calculator.dms(Calculator.fabs(x)));
  }


switch (key)
{
case keyPtolemaeus:
/* PTOLEMAEUS */
  if (traceMode) {
    trc.println("Ptolemäusschlüssel:\t 1° = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x))+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)));
    }
  return h.jd+tropicalYear*Calculator.fabs(x);

case keyNaibod:
/* Naibod */

  if (traceMode) {
    trc.println("Naibodschlüssel:\t" + Calculator.dms(naibod,Calculator.SEC) + " = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x)/naibod)+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)/naibod))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)/naibod));
    }
  return h.jd+tropicalYear*Calculator.fabs(x)/naibod;

case keyCardano:
/* Cardano */

  if (traceMode) {
    trc.println("Cardanoschlüssel:\t" + Calculator.dms(cardano,Calculator.SEC) + " = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x)/cardano)+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)/cardano))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)/cardano));
    }
  return h.jd+tropicalYear*Calculator.fabs(x)/cardano;

case keyProportional:
/* Proportionslschlüssel */

  if (traceMode) {
    trc.println("Proportionalschlüssel:\t" + Calculator.dms(proportional,Calculator.SEC) + " = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x)/proportional)+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)/proportional))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)/proportional));
    }
  return h.jd+tropicalYear*Calculator.fabs(x)/proportional;

case keyKuendig:
  d1 = Calculator.arcdiff(m.ramc(Math.ceil(h.pl(SweConst.SE_SUN))),
                          m.ramc(Math.floor(h.pl(SweConst.SE_SUN))));
  if (traceMode) {
    trc.println("Kündigschlüssel:\t" + Calculator.dms(d1,Calculator.SEC) + " = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x)/d1)+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)/d1))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)/d1));
    }
  return h.jd+tropicalYear*Calculator.fabs(x)/d1;


case keyTrueTime:
/* WAHRE ZEIT */

  xx = new double[6];
  coor = new double[3];
  serr = new StringBuffer();

  if (sl==null) sl = new SwissLib();

  /* Bestimme radikale RA der Sonne -> x2 */
  sl.swe_cotrans( new double[] {h.pl(SweConst.SE_SUN),h.pb(SweConst.SE_SUN),1d},0,coor,0,-m.ee());

  x0 = coor[0];
  x1=m.mclaenge(x0+x);
  /* x0+x = RA pro/re/gressive Sonne in Laenge umwandeln -> x1 */

  if (traceMode) {
    trc.println("RA Sonne radix:\t"+Calculator.dms(x0));
    trc.println("RA Sonne pr.:\t"+Calculator.dms(x0+x));
    trc.println("L Sonne pr.:\t"+Calculator.dms(x1,Calculator.ECL+Calculator.SEC));
    }

  d1 = h.jd + x/naibod;
  /* Ungefähres Erreichen der Sonnenlänge */

  se().swe_calc(d1,SweConst.SE_SUN, SweConst.SEFLG_SPEED,xx,serr);
  /* Startwert fuer das genaue Erreichen der progressiven Laenge */

  /* Schleife zur Bestimmung des genauen Zeitpunkts, an dem die
     progressive Sonne den durch den Direktionsbogen bestimmten
     ekliptikalen Laengenwert x1 erreicht                        */

  for(i=0;(Calculator.arcdiffAbs(x1,xx[0]) > Mundan.SPREC) &&(i<10);i++)
   /* bis Bogensekundengenauigkeit erreicht, aber hoechstens zehn
     Iterationen */
    {
    /* Bogendifferenz zum Zielwert x1 in Zeit umwandeln und an
       das Datum anbringen */
    d1 -= Calculator.arcdiff(xx[0],x1)/xx[3];
    /* Neuen Sonnenstand berechnen */
    se().swe_calc(d1,SweConst.SE_SUN, SweConst.SEFLG_SPEED,xx,serr);
    if (traceMode) {
       trc.println((i+1)+". Iteration Alter in d:\t" + (Math.round(10000*(d1-h.jd))/10000d)+"d");
       trc.println((i+1)+". Iteration L SO pr.:\t"+Calculator.dms(xx[0],Calculator.ECL+Calculator.SEC));
       }

    }

  if (i==10)
    {
    System.out.println("Genauigkeitsfehler bei der WZ-Berechnung!\n");
    if (traceMode) trc.println("Genauigkeitsfehler bei der WZ-Berechnung!\n");
    /* Diese Meldung sollte im Prinzip nie eintreten   */
    /* Tritt sie ein, so ist das ein Hinweis auf eine  */
    /* fehlerhafte CALC-Routine                        */
    return(-1);
    }

  if (traceMode) {
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(d1-h.jd))/10)));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(d1-h.jd)));
    }
  return h.jd+tropicalYear*Calculator.fabs(d1-h.jd);
  /* Ereigniszeit berechnen und zurueckgeben */

case keyDieiMotu:
  /* DIEI MOTU */
  d1 = h.dm(SweConst.SE_SUN)
     / (Math.pow(Calculator.cos(h.pl(SweConst.SE_SUN)),2)+Math.pow(Calculator.sin(h.pl(SweConst.SE_SUN))*Calculator.cos(m.ee()),2))
     *Calculator.cos(m.ee());
  if (traceMode) {
    trc.println("TB der SO in RA:\t" + Calculator.dms(d1) + " = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x)/d1)+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)/d1))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)/d1));
    }
  return h.jd+tropicalYear*Calculator.fabs(x)/d1;

  /* Formel: Tagesbewegung der Sonne in Aequatorgraden * x       */

case keyBessler:
  /* Sonnenlaenge */
  d1 = h.dm(SweConst.SE_SUN);
  if (traceMode) {
    trc.println("TB der SO in L:\t" + Calculator.dms(d1) + " = 1a");
    trc.println("Ereigniszeit:\t"+Math.round(tropicalYear*Calculator.fabs(x)/d1)+"d");
    trc.println("Julianisches Ereignisdatum:\t"+(Math.round(10*(h.jd+tropicalYear*Calculator.fabs(x)/d1))/10d));
    trc.println("=Ereignisdatum:\t"+Calculator.date(h.jd+tropicalYear*Calculator.fabs(x)/d1));
    }
  return h.jd+tropicalYear*Calculator.fabs(x)/d1;

} /* Switch */

/** Hier kommt er nie hin */
  return 0;

}

/** Berechnung der Promissorbreite. Es gibt traditionell verschiedene Verfahren,
wie die Breite eines Aspektpunktes zu berechnen ist. Viele Autoren ignorieren
die Promissorbreite vollständig (setzen sie also stets auf Null). Andere arbeiten
mit der <i>Bianchini</i>-Methode. Hierbei wird ein Hilfsgrosskreis verwendet,
der durch den Ort des Planeten und dessen Gegenort so verläuft, dass er die
Ekliptik in den beiden Quadraturstellen schneidet. Die Quadraturstellen bekommen
somit die Breite Null, die Oppositionsstelle den Breitenwert des Planeten, jedoch
mit entgegengesetztem Vorzeichen; für den Aspektwinkel a berechnet sich die Breite
b bei der breite bp des Planeten mit der Formel <code>sin(b) = cos(a)*sin(bp)</code>.
@param h Zugrundeliegendes Horoskop
@param i Nummer des Horoskopfaktors, der die Promissorstelle definiert (für zukünftige
Erweiterungen)
@param l Länge dieses Faktors (für zukünftige Erweiterungen)
@param b Breite dieses Faktors
@param asp Aspektwinkel
@param pbflag Gewünschte Methode der Breitenberechnung ( 0 = keine Breite, 1 = Bianchini)
@return Breite der Promissorstelle
*/
public double pbreite(
Horoscope h,         /* Radixstaende */
int i,               /* Nummer des beteiligten Faktors */
double l,            /* Seine Laenge */
double b,            /* Seine Breite */
double asp,          /* Aspekt       */
int pbflag           /* Gewuenschte Methode der Breitenberechnung */
)

{
double tb;
switch (pbflag) {
case 0:
  /* 0 = keine Promissorbreite */
  return 0.;

case 1:
  /* 1 = Bianchini-Formel */
  return Calculator.asin(Calculator.cos(asp)*Calculator.sin(b));

/* case 2: Morinus-Methode: noch zu implementieren */

} /* Switch */
/** Hier kommt er nie hin */
  return 0;

}


/** Setter-Methode für Direktionssystem */
public void setDirSystem( byte dirsystem ) {
  this.dirsystem = dirsystem;
  }


/** Setter-Methode für Direktionsschlüssel */
public void setKey( byte key ) {
  this.key = key;
  }


/** Liste aller in einem Zeitraum fälligen Direktionen */
public ArrayList getDirections( Horoscope h,
                                double t1,
                                double t2) {

   return getDirections( h,t1,t2, Horoscope.sensPtAll );

}

/** Liste aller in einem Zeitraum fälligen Direktionen aus vorgegebener
Aspektmenge. Es wird die als Parameter mitgegebene Aspekttafel zugrundegelegt. */
public ArrayList getDirections( Horoscope h,
                                double t1,
                                double t2,
                                ArrayList aspects ) {
  return getDirections(h,t1,t2,0, aspects);
  }

/** Liste aller in einem Zeitraum fälligen Direktionen zum vorgegebenen Aspektartparameter.  */
public ArrayList getDirections( Horoscope h,
                                double t1,
                                double t2,
                                long filter ) {
  return getDirections(h,t1,t2,filter, null);
  }

/** Liste aller in einem Zeitraum fälligen Direktionen zum vorgegebenen Aspektartparameter
und zu vorgegebener Aspektliste. */
public ArrayList getDirections( Horoscope h,
                                double t1,
                                double t2,
                                long filter,
                                ArrayList aspects) {

  return getDirections(h,t1,t2,filter, aspects, new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12} );

  }


/** Liste aller in einem Zeitraum fälligen Direktionen zum vorgegebenen Aspektartparameter
und zu vorgegebener Aspekt- und Signifikatorenliste. */
public ArrayList getDirections( Horoscope h,
                                double t1,
                                double t2,
                                long filter,
                                ArrayList aspects,
                                int[] sigList ) {

  int i,ii,ipl,k;
  double l1, l2, db1, db2, db,ls,bs;
  Mundan m = new Mundan( h );
  Iterator aIt;
  AspectPoint a;
  Direction d;
  ArrayList table = new ArrayList();
  boolean convers = false;

  // Definiert [t1,t2] ein Intervall?
  if (t1 >= t2) return table;

  // Die Methode zweimal durchlaufen, für direkte und converse Direktionen
  do {

  // Anfangs- und Endzeit in Direktionsbögen umrechnen
  db1 = dbogen( h, t1, convers);
  db2 = dbogen( h, t2, convers);

  // Übergebene Liste von Signifikatoren abarbeiten
  for (ii = 0; ii < sigList.length;  ii++ ) {
    // i ist der ii-te Signifikator der Liste
    i = sigList[ii];
    // Erlaubte Signifikatoren sind: Planeten, ASC oder MC
    if (i < Horoscope.maxPlanets) { ls = h.pl(i); bs = h.pb(i); ipl=i; }
    else if (i == Horoscope.maxPlanets) { ls = h.h(1); bs = 0; ipl=Horoscope.houseRange+1;}
    else if (i == Horoscope.maxPlanets+1) { ls = h.h(10); bs = 0; ipl=Horoscope.houseRange+10; }
    else continue;

    // Wurde keine Aspektliste übergeben, so wird sie hier ermittelt:
    // Alle Aspekte in der durch [db1,db2] gegebenen Strecke, die der
    // Signifikator zurücklegt, zum angegebenen Filter
    if (aspects == null) {
      l1 = ldirekt( db1, ls, bs );
      l2 = ldirekt( db2, ls, bs );
      if (convers) aIt = h.getTransits(l2,l1,filter).iterator();
      else aIt = h.getTransits(l1,l2,filter).iterator();
      }
    else aIt = aspects.iterator();

    // Aspekte der Reihe nach durchgehen: Wird Direktion im
    // übergebenen Zeitintervall fällig?
    while (aIt.hasNext()) {
      a = (AspectPoint) aIt.next();
      // Aspekte von Achsen zu Achsen ignorieren
      if ( ( ipl >= Horoscope.houseRange ) && ( a.planet1 >= Horoscope.houseRange ) )
        continue;
      // Direktionsbogen berechnen
      db = calcdir(ls, bs, a.lon, 0d);

      // Fällt Direktionsbogen ins Intervall?
      if ( !convers && ((db < db1) || (db > db2)) ||
            convers && ((db > db1) || (db < db2)))
           continue;

      // Ja, dann Direktion in Ergebnisliste aufnehmen
      d = new Direction();
      d.sig  = ipl;
      d.ls   = ls;
      d.bs   = bs;
      d.prom = a;
      d.db   = db;
      d.jd   = ezeit( h, d.db );
      d.direct = !convers;
      d.ramc = m.st + db;
      // Direktion sortiert einfügen
      k = Collections.binarySearch(table, d);
      if (k < 0) k = -k-1;
      table.add(k,d);
      }
    }
    if (onlyDirect || convers) break;
    convers = !convers;
  } while (true);

  return table;

}

/** Eine Liste von Direktionen ausdrucken
@param d Liste von Direktionen
@param out Ausgabestream */
public static void printDirections( ArrayList d, PrintStream out) {
  Iterator dIt = d.iterator();
  int[] date;
  Direction dir;
  while (dIt.hasNext()) {

// Datum in Kalenderdatum konvertieren
    dir = (Direction) (dIt.next());
    date = Calculator.calendarDate(dir.jd);
    out.print(date[0]+"."+date[1]+"."+date[2]+"\t");

// Direktionsformel
    out.print( dir + "\t");

// Direktionsbogen
    out.print(Calculator.dms(dir.db,Calculator.GEO|Calculator.SEC)+"\t");

// Ekliptikale Länge
    out.print(Calculator.dms(dir.prom.lon,Calculator.ECL+Calculator.SEC)+"  ");

// Zeilenvorschub
    out.println();
    }
  }


  /** Den Trace-Modus aktivieren. Die Methoden zur Direktionsberechnung
  schreiben dann ihr Zwischenergebnisse in die Standardausgabe */
  public void setTraceMode() {
    traceMode = true;
    trc = new PrintWriter( System.out );
    }


  /** Den Trace-Modus aktivieren. Die Zwischenergebnisse werden nicht
  in der Standard-Ausgabe, sondern in einen beliebigen anderen <code>Writer</code>
  ausgegeben. */
  public void setTraceMode(Writer itrc) {
    traceMode = true;
    trc  = new PrintWriter( itrc );
    }

  /** Trace-Modus wieder deaktivieren */
  public void resetTraceMode() {
    traceMode = false;
    }


  /** "Direkte Stände" bestimmen. Dieses symbolische "vorgeschobene" Horoskop
  zeigt die Ekliptikpunkte, die als Promissor zum angegebenen Direktionsbogen
  genau die mundanen Positionen der Häuser und Planeten des Radixhoroskops
  realisieren. Damit diese Methode aufrufbar ist, muss die Instanz der Klasse
  <code>Direct</code> mit einem <code>Horoscope</code>-Exemplar, dem Radixhoroskop,
  gebildet worden sein.
  @param db Direktionsbogen
  @param house Ein double[13] Array, der die "dirigierten Häuserspitzen" enthält,
  also diejenigen Ekliptikpunkte, die, primär um den Bogen <code>db</code> geführt,
  die Häuserspitzen des Radixhoroskops ergeben.
  @param planet Ein double[10] Array, der die "dirigierten Planetenstände" enthält,
  also diejenigen Ekliptikpunkte, die, primär um den Bogen <code>db</code> geführt,
  die mundane Position des entsprechenden Radixplaneten einnehmen.*/
  public void directPositions(double db, double[] house, double[] planet) {
    int i;
    if (this.h == null) return;
    for (i=0;i<10;i++) planet[i] = ldirekt( db, h.pl(i), h.pb(i) );
    for (i=1;i<13;i++) house[i]  = ldirekt( db, h.h(i), 0d );
    }


}





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