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

Klasse Degree

Javadoc von Degree   Degree.java herunterladen

package AstroOL;

import java.util.Vector;
import java.util.Enumeration;

/** Wrapperklasse für Sexagesimalzahlen.
Ähnlich wie java.lang.Double ist AstroOL.Degree
eine umhüllende Klasse (Wrapperklasse) für eine
doppeltgenaue Gleitkommazahl (<code>double</code>).
Eine Instanz dieser Klasse repräsentiert eine Angabe
im Sexagesimalsystem (Position im Tierkreis, Uhrzeit,
geographische Längen- oder Breitenangabe). Sie enthält
Methoden zum Einlesen (Parsen) von sexagesimalen Zahlen
sowie zur Ausgabe in einem geeigneten Format.
 */
public class Degree {

/** Genauigkeit Minuten oder Sekunden - Default Sekunden */
  public static boolean minutesOnly = false;

/** Runden - Default ja */
  public static boolean round = true;

/** Intern ist ein Objekt dieser Klasse einfach ein double, repräsentiert den Wert <code>value</code> */
  private double decimalValue;

/** Instanz zum Wert 0 bilden (leerer Konstruktor). */
  public Degree() {
    this(0d);
    }

/** Konstruktor für bekannte Gleitommazahl */
  public Degree(double x) {
   int circle = 360;
   decimalValue = x;
    if ( x < 0 ) circle = -circle;
    while ( decimalValue < 0 || decimalValue >= circle)
      decimalValue -= circle;
    }

/** Kopier-Konstruktor */
  public Degree(Degree d) {
    this( d.decimalValue );
    }

/** Zuerst Sexagesimalzahl parsen */
  public Degree(String s) {
    decimalValue = getValue(s);
    }

/** Getter-Methode für zugrundeliegende Gleitkommazahl */
  public double getValue() {
    return decimalValue;
    }

/** Eine Sexagesimalzahl interpretieren */
  public static double getValue(String s) {
    StringBuffer prefix = new StringBuffer();
    long    numerator    = 0,
            denominator = 1;
    int     i            = 0;
    boolean first        = true,
            negative     = false;
    Vector  number       = new Vector(3),
            delimiter    = new Vector(3);
    Integer element;
    double  x;

    parse( s, prefix, number, delimiter );
    Enumeration e = number.elements();
    x = 0d;
    while (e.hasMoreElements()) {
       numerator = numerator * 60 + ((Integer)e.nextElement()).intValue();
       if (first) {
         if (numerator < 0) {
           negative = true;
           numerator = -numerator;
           }
         first = false;
         }
       else
         denominator *= 60;
       }
    if (negative) numerator = -numerator;
    x = (double) numerator / denominator;
    if (delimiter.size() > 0) {
// Tierkreiszeichen-Kurzform interpretieren
        i = -1;
        if ((i = signNumber(delimiter.elementAt(0).toString())) < 0 )
          if ( (delimiter.size() == 3) &&
               ((i =  signNumber(delimiter.elementAt(2).toString())) < 0))
            if (delimiter.size() == 2)
                 i =  signNumber(delimiter.elementAt(1).toString());
        if ((i >= 0) )
          x = Calculator.fmod360(x + (negative ? -30*i : 30*i));
        else if ("ws".indexOf(delimiter.elementAt(0).toString().toLowerCase()) >=0)
          x = (negative) ? x : -x;
      }
    return x;
    }

/** Nummer des Tierkreiszeichens (AR = 0, TA = 1, ...) ermitteln */
  public static int signNumber(String sign) {
    if (sign.length() != 2) return -1;
    int i = Calculator.sknam.indexOf(sign.toUpperCase());
    if ((i%2)!=0) return -1;
    else return i/2;
    }

/** Ausgabefunktion - identisch zu dms() */
  public String toString() {
    return dms(decimalValue, "°", "'", "\"", minutesOnly, round);
    }


/** Einen String erzeugen, der die Sexagesimalzahl dieses Objekts darstellt. */
  public String dms() {
    return dms(decimalValue,"°", "'", "\"", minutesOnly, round);
    }

/** Einen String erzeugen, der die übergebene Sexagesimalzahl darstellt. */
  public static String dms(double x) {
    return dms(x, "°", "'", "\"", minutesOnly, round);
    }

/** Einen String erzeugen, der die übergebene Sexagesimalzahl darstellt; Trennzeichen
oder -string für die Gradzahl ist frei wählbar. */
  public static String dms(double x, String DegDel) {
    return dms(x, DegDel, "'", "\"", minutesOnly, round);
    }

/** Einen String erzeugen, der die übergebene Sexagesimalzahl darstellt; Trennzeichen
oder -strings zwischen den Zahlwerten für Grade, Minuten und Sekunden sind frei wählbar. */
  public static String dms(double x,
                    String DegreeDel,
                    String MinDel,
                    String SecDel) {
    return dms(x, DegreeDel, MinDel, SecDel, minutesOnly, round);
    }

/** Einen String in eine alternierende Sequenz von Zahl und Nicht-Zahl zerlegen. Die Zerlegung
geschieht nach folgendem Muster:
<pre>
// NotANumber Number    NotANumber   Number    NotANumber   ...
// (prefix)   number(1) delimiter(1) number(2) delimiter(2) ...
</pre>
*/
  public static  void parse( String in,
                            StringBuffer prefix,
                            Vector number,
                            Vector delimiter ) {
     int i, j, l, lastcut = 0;
     boolean first = true,
             wasNumeric = false,
             isNumeric = false;
     StringBuffer delim = new StringBuffer(1);
     char c = ' ';

     prefix.setLength(0);
     l = in.length();
     for( i = 0; i <= l; i++ ) {

       if (i < l) {
         c = in.charAt(i);
         c = Character.toUpperCase(c);
         if (Character.isWhitespace(c)) continue;
         isNumeric =  Character.isDigit(c);
         }

// Typsprung?
       if (i != 0 && (isNumeric != wasNumeric) || (i == l)) {
         if (wasNumeric) {
           number.addElement(new Integer(delim.toString()));
           }
         else
           if (first) {
             prefix.append(delim.toString());
             }
           else {
             delimiter.addElement(delim);
             }
         lastcut = i;
         delim = new StringBuffer(1);
         first = false;
         }
       delim.append(c);
       wasNumeric = isNumeric;
    }
  }

/** Einen Gradwert als String mit frei wählbaren Trennzeichen zwischen den Zahlwerten für
Grade, Minuten und Sekunden darstellen. Darüberhinaus kann bestimmt werden, ob die Darstellung
nur minutengenau sein soll und ob gerundet werden soll. */
public static String dms(double x,
                    String DegreeDel,
                    String MinDel,
                    String SecDel,
                    boolean minutesOnly,
                    boolean round) {
    String result;
    double lx;
    int d;
    byte m,s;
    char sign;

// Lokale Kopie erstellen, da Wert verändert wird
    lx = x;

// Vorzeichen merken, Absolutwert nehmen
   if ( lx < 0 ) {
     sign = '-';
     lx = -lx;
     }
   else
     sign = ' ';


// Runden? Dann .5' oder .5" addieren
    if (round)
      if (minutesOnly)
// Sicherstellen, dass auch für exakt .5' oder .5"
// gerundet wird: Kleine Zahl hinzuzählen
        lx += .5d/60 + 1.e-12d;
      else
        lx += .5d/3600 + 1.e-12d;

// Grade ermitteln, in Ergebnis schieben
    d = (int) lx;
    if (d < 10)
      result = "  " + sign + d;
    else if (d < 100)
      result = " " + sign + d;
    else
      result = sign + "" + d;
// Grad-Suffix
    result = result + DegreeDel;

// Minuten
    m = (byte) ( ( lx - d ) * 60 );
    if (m < 10)
      result = result + " " + m;
    else
      result = result + m;
// Minuten-Suffix
    result = result + MinDel;

// Sekunden
    s = (byte) ( (( lx - d ) * 60 - m ) * 60. );
    if (!minutesOnly) {
      if (s < 10)
        result = result + " " + s;
      else
        result = result + s;
// Sekunden-Suffix
      result = result + SecDel;
    }

    return result;

    }


/** Die dieses Objekt repräsentierende Gleitkommazahl als zodiakalen Längenwert darstellen. */
    public String zodLength() {
      return zodLength(decimalValue);
      }

/** Die mit dem Aufruf übergebene Gleitkommazahl als zodiakalen Längenwert darstellen. */
    public static String zodLength(double x) {

      double x1;
      int offset;
      x1 = ( x/360 - Math.floor(x/360))*360;
      offset = ((int) x1 / 30)*2;
      x1 = ( x1/30d - Math.floor(x1/30d))*30;
      if (x1 >= 29.99986111) { x1 = 0; offset = (offset+2) % 12; }
      return dms(x1) + Calculator.sknam.substring(offset,offset+2);

      }

  }  // Class Degree



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