tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

astro.h (14917B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /************************************************************************
      4 * Copyright (C) 1996-2008, International Business Machines Corporation *
      5 * and others. All Rights Reserved.                                     *
      6 ************************************************************************
      7 *  2003-nov-07   srl       Port from Java
      8 */
      9 
     10 #ifndef ASTRO_H
     11 #define ASTRO_H
     12 
     13 #include "unicode/utypes.h"
     14 
     15 #if !UCONFIG_NO_FORMATTING
     16 
     17 #include "gregoimp.h"  // for Math
     18 #include "unicode/unistr.h"
     19 
     20 U_NAMESPACE_BEGIN
     21 
     22 /**
     23 * <code>CalendarAstronomer</code> is a class that can perform the calculations to
     24 * determine the positions of the sun and moon, the time of sunrise and
     25 * sunset, and other astronomy-related data.  The calculations it performs
     26 * are in some cases quite complicated, and this utility class saves you
     27 * the trouble of worrying about them.
     28 * <p>
     29 * The measurement of time is a very important part of astronomy.  Because
     30 * astronomical bodies are constantly in motion, observations are only valid
     31 * at a given moment in time.  Accordingly, each <code>CalendarAstronomer</code>
     32 * object has a <code>time</code> property that determines the date
     33 * and time for which its calculations are performed.  You can set and
     34 * retrieve this property with {@link #setTime setTime}, {@link #getTime getTime}
     35 * and related methods.
     36 * <p>
     37 * Almost all of the calculations performed by this class, or by any
     38 * astronomer, are approximations to various degrees of accuracy.  The
     39 * calculations in this class are mostly modelled after those described
     40 * in the book
     41 * <a href="http://www.amazon.com/exec/obidos/ISBN=0521356997" target="_top">
     42 * Practical Astronomy With Your Calculator</a>, by Peter J.
     43 * Duffett-Smith, Cambridge University Press, 1990.  This is an excellent
     44 * book, and if you want a greater understanding of how these calculations
     45 * are performed it a very good, readable starting point.
     46 * <p>
     47 * <strong>WARNING:</strong> This class is very early in its development, and
     48 * it is highly likely that its API will change to some degree in the future.
     49 * At the moment, it basically does just enough to support {@link IslamicCalendar}
     50 * and {@link ChineseCalendar}.
     51 *
     52 * @author Laura Werner
     53 * @author Alan Liu
     54 * @internal
     55 */
     56 class U_I18N_API CalendarAstronomer : public UMemory {
     57 public:
     58  // some classes
     59 
     60 public:
     61  /**
     62   * Represents the position of an object in the sky relative to the ecliptic,
     63   * the plane of the earth's orbit around the Sun.
     64   * This is a spherical coordinate system in which the latitude
     65   * specifies the position north or south of the plane of the ecliptic.
     66   * The longitude specifies the position along the ecliptic plane
     67   * relative to the "First Point of Aries", which is the Sun's position in the sky
     68   * at the Vernal Equinox.
     69   * <p>
     70   * Note that Ecliptic objects are immutable and cannot be modified
     71   * once they are constructed.  This allows them to be passed and returned by
     72   * value without worrying about whether other code will modify them.
     73   *
     74   * @see CalendarAstronomer.Equatorial
     75   * @internal
     76   */
     77  class U_I18N_API Ecliptic : public UMemory {
     78  public:
     79    /**
     80     * Constructs an Ecliptic coordinate object.
     81     * <p>
     82     * @param lat The ecliptic latitude, measured in radians.
     83     * @param lon The ecliptic longitude, measured in radians.
     84     * @internal
     85     */
     86    Ecliptic(double lat = 0, double lon = 0) {
     87      latitude = lat;
     88      longitude = lon;
     89    }
     90 
     91    /**
     92     * Setter for Ecliptic Coordinate object
     93     * @param lat The ecliptic latitude, measured in radians.
     94     * @param lon The ecliptic longitude, measured in radians.
     95     * @internal
     96     */
     97    void set(double lat, double lon) {
     98      latitude = lat;
     99      longitude = lon;
    100    }
    101 
    102    /**
    103     * Return a string representation of this object
    104     * @internal
    105     */
    106    UnicodeString toString() const;
    107 
    108    /**
    109     * The ecliptic latitude, in radians.  This specifies an object's
    110     * position north or south of the plane of the ecliptic,
    111     * with positive angles representing north.
    112     * @internal
    113     */
    114    double latitude;
    115 
    116    /**
    117     * The ecliptic longitude, in radians.
    118     * This specifies an object's position along the ecliptic plane
    119     * relative to the "First Point of Aries", which is the Sun's position
    120     * in the sky at the Vernal Equinox,
    121     * with positive angles representing east.
    122     * <p>
    123     * A bit of trivia: the first point of Aries is currently in the
    124     * constellation Pisces, due to the precession of the earth's axis.
    125     * @internal
    126     */
    127    double longitude;
    128  };
    129 
    130  /**
    131   * Represents the position of an
    132   * object in the sky relative to the plane of the earth's equator.
    133   * The <i>Right Ascension</i> specifies the position east or west
    134   * along the equator, relative to the sun's position at the vernal
    135   * equinox.  The <i>Declination</i> is the position north or south
    136   * of the equatorial plane.
    137   * <p>
    138   * Note that Equatorial objects are immutable and cannot be modified
    139   * once they are constructed.  This allows them to be passed and returned by
    140   * value without worrying about whether other code will modify them.
    141   *
    142   * @see CalendarAstronomer.Ecliptic
    143   * @internal
    144   */
    145  class U_I18N_API Equatorial : public UMemory {
    146  public:
    147    /**
    148     * Constructs an Equatorial coordinate object.
    149     * <p>
    150     * @param asc The right ascension, measured in radians.
    151     * @param dec The declination, measured in radians.
    152     * @internal
    153     */
    154    Equatorial(double asc = 0, double dec = 0)
    155      : ascension(asc), declination(dec) { }
    156 
    157    /**
    158     * Setter
    159     * @param asc The right ascension, measured in radians.
    160     * @param dec The declination, measured in radians.
    161     * @internal
    162     */
    163    void set(double asc, double dec) {
    164      ascension = asc;
    165      declination = dec;
    166    }
    167 
    168    /**
    169     * Return a string representation of this object, with the
    170     * angles measured in degrees.
    171     * @internal
    172     */
    173    UnicodeString toString() const;
    174 
    175    /**
    176     * Return a string representation of this object with the right ascension
    177     * measured in hours, minutes, and seconds.
    178     * @internal
    179     */
    180    //String toHmsString() {
    181    //return radToHms(ascension) + "," + radToDms(declination);
    182    //}
    183 
    184    /**
    185     * The right ascension, in radians.
    186     * This is the position east or west along the equator
    187     * relative to the sun's position at the vernal equinox,
    188     * with positive angles representing East.
    189     * @internal
    190     */
    191    double ascension;
    192 
    193    /**
    194     * The declination, in radians.
    195     * This is the position north or south of the equatorial plane,
    196     * with positive angles representing north.
    197     * @internal
    198     */
    199    double declination;
    200  };
    201 
    202 public:
    203  //-------------------------------------------------------------------------
    204  // Assorted private data used for conversions
    205  //-------------------------------------------------------------------------
    206 
    207  // My own copies of these so compilers are more likely to optimize them away
    208  static const double PI;
    209 
    210  /**
    211   * The average number of solar days from one new moon to the next.  This is the time
    212   * it takes for the moon to return the same ecliptic longitude as the sun.
    213   * It is longer than the sidereal month because the sun's longitude increases
    214   * during the year due to the revolution of the earth around the sun.
    215   * Approximately 29.53.
    216   *
    217   * @see #SIDEREAL_MONTH
    218   * @internal
    219   * @deprecated ICU 2.4. This class may be removed or modified.
    220   */
    221  static const double SYNODIC_MONTH;
    222 
    223  //-------------------------------------------------------------------------
    224  // Constructors
    225  //-------------------------------------------------------------------------
    226 
    227  /**
    228   * Construct a new <code>CalendarAstronomer</code> object that is initialized to
    229   * the current date and time.
    230   * @internal
    231   */
    232  CalendarAstronomer();
    233 
    234  /**
    235   * Construct a new <code>CalendarAstronomer</code> object that is initialized to
    236   * the specified date and time.
    237   * @internal
    238   */
    239  CalendarAstronomer(UDate d);
    240 
    241  /**
    242   * Destructor
    243   * @internal
    244   */
    245  ~CalendarAstronomer();
    246 
    247  //-------------------------------------------------------------------------
    248  // Time and date getters and setters
    249  //-------------------------------------------------------------------------
    250 
    251  /**
    252   * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
    253   * astronomical calculations are performed based on this time setting.
    254   *
    255   * @param aTime the date and time, expressed as the number of milliseconds since
    256   *              1/1/1970 0:00 GMT (Gregorian).
    257   *
    258   * @see #getTime
    259   * @internal
    260   */
    261  void setTime(UDate aTime);
    262 
    263  /**
    264   * Get the current time of this <code>CalendarAstronomer</code> object,
    265   * represented as the number of milliseconds since
    266   * 1/1/1970 AD 0:00 GMT (Gregorian).
    267   *
    268   * @see #setTime
    269   * @internal
    270   */
    271  UDate getTime();
    272 
    273  /**
    274   * Get the current time of this <code>CalendarAstronomer</code> object,
    275   * expressed as a "julian day number", which is the number of elapsed
    276   * days since 1/1/4713 BC (Julian), 12:00 GMT.
    277   *
    278   * @see #JULIAN_EPOCH_MS
    279   * @internal
    280   */
    281  double getJulianDay();
    282 
    283 public:
    284  /**
    285   * Convert from ecliptic to equatorial coordinates.
    286   *
    287   * @param eclipLong     The ecliptic longitude
    288   * @param eclipLat      The ecliptic latitude
    289   *
    290   * @return              The corresponding point in equatorial coordinates.
    291   * @internal
    292   */
    293  Equatorial& eclipticToEquatorial(Equatorial& result, double eclipLong, double eclipLat);
    294 
    295  //-------------------------------------------------------------------------
    296  // The Sun
    297  //-------------------------------------------------------------------------
    298 
    299  /**
    300   * The longitude of the sun at the time specified by this object.
    301   * The longitude is measured in radians along the ecliptic
    302   * from the "first point of Aries," the point at which the ecliptic
    303   * crosses the earth's equatorial plane at the vernal equinox.
    304   * <p>
    305   * Currently, this method uses an approximation of the two-body Kepler's
    306   * equation for the earth and the sun.  It does not take into account the
    307   * perturbations caused by the other planets, the moon, etc.
    308   * @internal
    309   */
    310  double getSunLongitude();
    311 
    312  /**
    313   * TODO Make this public when the entire class is package-private.
    314   */
    315  /*public*/ void getSunLongitude(double julianDay, double &longitude, double &meanAnomaly);
    316 
    317 public:
    318  /**
    319   * Constant representing the winter solstice.
    320   * For use with {@link #getSunTime getSunTime}.
    321   * Note: In this case, "winter" refers to the northern hemisphere's seasons.
    322   * @internal
    323   */
    324  static double WINTER_SOLSTICE();
    325 
    326  /**
    327   * Find the next time at which the sun's ecliptic longitude will have
    328   * the desired value.
    329   * @internal
    330   */
    331  UDate getSunTime(double desired, UBool next);
    332 
    333  //-------------------------------------------------------------------------
    334  // The Moon
    335  //-------------------------------------------------------------------------
    336 
    337  /**
    338   * The position of the moon at the time set on this
    339   * object, in equatorial coordinates.
    340   * @internal
    341   * @return const reference to internal field of calendar astronomer. Do not use outside of the lifetime of this astronomer.
    342   */
    343  const Equatorial& getMoonPosition();
    344 
    345  /**
    346   * The "age" of the moon at the time specified in this object.
    347   * This is really the angle between the
    348   * current ecliptic longitudes of the sun and the moon,
    349   * measured in radians.
    350   *
    351   * @see #getMoonPhase
    352   * @internal
    353   */
    354  double getMoonAge();
    355 
    356  class U_I18N_API MoonAge : public UMemory {
    357  public:
    358    MoonAge(double l)
    359      :  value(l) { }
    360    void set(double l) { value = l; }
    361    double value;
    362  };
    363 
    364  /**
    365   * Constant representing a new moon.
    366   * For use with {@link #getMoonTime getMoonTime}
    367   * @internal
    368   */
    369  static MoonAge NEW_MOON();
    370 
    371  /**
    372   * Find the next or previous time at which the Moon's ecliptic
    373   * longitude will have the desired value.
    374   * <p>
    375   * @param desired   The desired longitude.
    376   * @param next      <tt>true</tt> if the next occurrence of the phase
    377   *                  is desired, <tt>false</tt> for the previous occurrence.
    378   * @internal
    379   */
    380  UDate getMoonTime(const MoonAge& desired, UBool next);
    381 
    382  //-------------------------------------------------------------------------
    383  // Interpolation methods for finding the time at which a given event occurs
    384  //-------------------------------------------------------------------------
    385 
    386 public:
    387  class AngleFunc : public UMemory {
    388  public:
    389    virtual double eval(CalendarAstronomer&) = 0;
    390    virtual ~AngleFunc();
    391  };
    392  friend class AngleFunc;
    393 
    394 private:
    395  UDate timeOfAngle(AngleFunc& func, double desired,
    396                    double periodDays, double epsilon, UBool next);
    397 
    398  //-------------------------------------------------------------------------
    399  // Other utility methods
    400  //-------------------------------------------------------------------------
    401 private:
    402 
    403  /**
    404   * Return the obliquity of the ecliptic (the angle between the ecliptic
    405   * and the earth's equator) at the current time.  This varies due to
    406   * the precession of the earth's axis.
    407   *
    408   * @return  the obliquity of the ecliptic relative to the equator,
    409   *          measured in radians.
    410   */
    411  double eclipticObliquity();
    412 
    413  //-------------------------------------------------------------------------
    414  // Private data
    415  //-------------------------------------------------------------------------
    416 private:
    417  /**
    418   * Current time in milliseconds since 1/1/1970 AD
    419   * @see java.util.Date#getTime
    420   */
    421  UDate fTime;
    422 
    423  // The following fields are used to cache calculated results for improved
    424  // performance.  These values all depend on the current time setting
    425  // of this object, so the clearCache method is provided.
    426  double    julianDay;
    427  double    sunLongitude;
    428  double    meanAnomalySun;
    429  double    moonEclipLong;
    430 
    431  void clearCache();
    432 
    433  Equatorial  moonPosition;
    434  UBool       moonPositionSet;
    435 
    436  /**
    437   * @internal
    438   */
    439 //  UDate local(UDate localMillis);
    440 };
    441 
    442 U_NAMESPACE_END
    443 
    444 struct UHashtable;
    445 
    446 U_NAMESPACE_BEGIN
    447 
    448 /**
    449 * Cache of month -> julian day
    450 * @internal
    451 */
    452 class CalendarCache : public UMemory {
    453 public:
    454  static int32_t get(CalendarCache** cache, int32_t key, UErrorCode &status);
    455  static void put(CalendarCache** cache, int32_t key, int32_t value, UErrorCode &status);
    456  virtual ~CalendarCache();
    457 private:
    458  CalendarCache(int32_t size, UErrorCode& status);
    459  static void createCache(CalendarCache** cache, UErrorCode& status);
    460  /**
    461   * not implemented
    462   */
    463  CalendarCache();
    464  UHashtable *fTable;
    465 };
    466 
    467 U_NAMESPACE_END
    468 
    469 #endif
    470 #endif