intl/icu/source/i18n/astro.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /************************************************************************
     2  * Copyright (C) 1996-2008, International Business Machines Corporation *
     3  * and others. All Rights Reserved.                                     *
     4  ************************************************************************
     5  *  2003-nov-07   srl       Port from Java
     6  */
     8 #ifndef ASTRO_H
     9 #define ASTRO_H
    11 #include "unicode/utypes.h"
    13 #if !UCONFIG_NO_FORMATTING
    15 #include "gregoimp.h"  // for Math
    16 #include "unicode/unistr.h"
    18 U_NAMESPACE_BEGIN
    20 /**
    21  * <code>CalendarAstronomer</code> is a class that can perform the calculations to
    22  * determine the positions of the sun and moon, the time of sunrise and
    23  * sunset, and other astronomy-related data.  The calculations it performs
    24  * are in some cases quite complicated, and this utility class saves you
    25  * the trouble of worrying about them.
    26  * <p>
    27  * The measurement of time is a very important part of astronomy.  Because
    28  * astronomical bodies are constantly in motion, observations are only valid
    29  * at a given moment in time.  Accordingly, each <code>CalendarAstronomer</code>
    30  * object has a <code>time</code> property that determines the date
    31  * and time for which its calculations are performed.  You can set and
    32  * retrieve this property with {@link #setDate setDate}, {@link #getDate getDate}
    33  * and related methods.
    34  * <p>
    35  * Almost all of the calculations performed by this class, or by any
    36  * astronomer, are approximations to various degrees of accuracy.  The
    37  * calculations in this class are mostly modelled after those described
    38  * in the book
    39  * <a href="http://www.amazon.com/exec/obidos/ISBN=0521356997" target="_top">
    40  * Practical Astronomy With Your Calculator</a>, by Peter J.
    41  * Duffett-Smith, Cambridge University Press, 1990.  This is an excellent
    42  * book, and if you want a greater understanding of how these calculations
    43  * are performed it a very good, readable starting point.
    44  * <p>
    45  * <strong>WARNING:</strong> This class is very early in its development, and
    46  * it is highly likely that its API will change to some degree in the future.
    47  * At the moment, it basically does just enough to support {@link IslamicCalendar}
    48  * and {@link ChineseCalendar}.
    49  *
    50  * @author Laura Werner
    51  * @author Alan Liu
    52  * @internal
    53  */
    54 class U_I18N_API CalendarAstronomer : public UMemory {
    55 public:
    56   // some classes
    58 public:
    59   /**
    60    * Represents the position of an object in the sky relative to the ecliptic,
    61    * the plane of the earth's orbit around the Sun.
    62    * This is a spherical coordinate system in which the latitude
    63    * specifies the position north or south of the plane of the ecliptic.
    64    * The longitude specifies the position along the ecliptic plane
    65    * relative to the "First Point of Aries", which is the Sun's position in the sky
    66    * at the Vernal Equinox.
    67    * <p>
    68    * Note that Ecliptic objects are immutable and cannot be modified
    69    * once they are constructed.  This allows them to be passed and returned by
    70    * value without worrying about whether other code will modify them.
    71    *
    72    * @see CalendarAstronomer.Equatorial
    73    * @see CalendarAstronomer.Horizon
    74    * @internal
    75    */
    76   class U_I18N_API Ecliptic : public UMemory {
    77   public:
    78     /**
    79      * Constructs an Ecliptic coordinate object.
    80      * <p>
    81      * @param lat The ecliptic latitude, measured in radians.
    82      * @param lon The ecliptic longitude, measured in radians.
    83      * @internal
    84      */
    85     Ecliptic(double lat = 0, double lon = 0) {
    86       latitude = lat;
    87       longitude = lon;
    88     }
    90     /**
    91      * Setter for Ecliptic Coordinate object
    92      * @param lat The ecliptic latitude, measured in radians.
    93      * @param lon The ecliptic longitude, measured in radians.
    94      * @internal
    95      */
    96     void set(double lat, double lon) {
    97       latitude = lat;
    98       longitude = lon;
    99     }
   101     /**
   102      * Return a string representation of this object
   103      * @internal
   104      */
   105     UnicodeString toString() const;
   107     /**
   108      * The ecliptic latitude, in radians.  This specifies an object's
   109      * position north or south of the plane of the ecliptic,
   110      * with positive angles representing north.
   111      * @internal
   112      */
   113     double latitude;
   115     /**
   116      * The ecliptic longitude, in radians.
   117      * This specifies an object's position along the ecliptic plane
   118      * relative to the "First Point of Aries", which is the Sun's position
   119      * in the sky at the Vernal Equinox,
   120      * with positive angles representing east.
   121      * <p>
   122      * A bit of trivia: the first point of Aries is currently in the
   123      * constellation Pisces, due to the precession of the earth's axis.
   124      * @internal
   125      */
   126     double longitude;
   127   };
   129   /**
   130    * Represents the position of an
   131    * object in the sky relative to the plane of the earth's equator.
   132    * The <i>Right Ascension</i> specifies the position east or west
   133    * along the equator, relative to the sun's position at the vernal
   134    * equinox.  The <i>Declination</i> is the position north or south
   135    * of the equatorial plane.
   136    * <p>
   137    * Note that Equatorial objects are immutable and cannot be modified
   138    * once they are constructed.  This allows them to be passed and returned by
   139    * value without worrying about whether other code will modify them.
   140    *
   141    * @see CalendarAstronomer.Ecliptic
   142    * @see CalendarAstronomer.Horizon
   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) { }
   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     }
   168     /**
   169      * Return a string representation of this object, with the
   170      * angles measured in degrees.
   171      * @internal
   172      */
   173     UnicodeString toString() const;
   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     //}
   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;
   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   };
   202   /**
   203    * Represents the position of an  object in the sky relative to
   204    * the local horizon.
   205    * The <i>Altitude</i> represents the object's elevation above the horizon,
   206    * with objects below the horizon having a negative altitude.
   207    * The <i>Azimuth</i> is the geographic direction of the object from the
   208    * observer's position, with 0 representing north.  The azimuth increases
   209    * clockwise from north.
   210    * <p>
   211    * Note that Horizon objects are immutable and cannot be modified
   212    * once they are constructed.  This allows them to be passed and returned by
   213    * value without worrying about whether other code will modify them.
   214    *
   215    * @see CalendarAstronomer.Ecliptic
   216    * @see CalendarAstronomer.Equatorial
   217    * @internal
   218    */
   219   class U_I18N_API Horizon : public UMemory {
   220   public:
   221     /**
   222      * Constructs a Horizon coordinate object.
   223      * <p>
   224      * @param alt  The altitude, measured in radians above the horizon.
   225      * @param azim The azimuth, measured in radians clockwise from north.
   226      * @internal
   227      */
   228     Horizon(double alt=0, double azim=0)
   229       : altitude(alt), azimuth(azim) { }
   231     /**
   232      * Setter for Ecliptic Coordinate object
   233      * @param alt  The altitude, measured in radians above the horizon.
   234      * @param azim The azimuth, measured in radians clockwise from north.
   235      * @internal
   236      */
   237     void set(double alt, double azim) {
   238       altitude = alt;
   239       azimuth = azim;
   240     }
   242     /**
   243      * Return a string representation of this object, with the
   244      * angles measured in degrees.
   245      * @internal
   246      */
   247     UnicodeString toString() const;
   249     /**
   250      * The object's altitude above the horizon, in radians.
   251      * @internal
   252      */
   253     double altitude;
   255     /**
   256      * The object's direction, in radians clockwise from north.
   257      * @internal
   258      */
   259     double azimuth;
   260   };
   262 public:
   263   //-------------------------------------------------------------------------
   264   // Assorted private data used for conversions
   265   //-------------------------------------------------------------------------
   267   // My own copies of these so compilers are more likely to optimize them away
   268   static const double PI;
   270   /**
   271    * The average number of solar days from one new moon to the next.  This is the time
   272    * it takes for the moon to return the same ecliptic longitude as the sun.
   273    * It is longer than the sidereal month because the sun's longitude increases
   274    * during the year due to the revolution of the earth around the sun.
   275    * Approximately 29.53.
   276    *
   277    * @see #SIDEREAL_MONTH
   278    * @internal
   279    * @deprecated ICU 2.4. This class may be removed or modified.
   280    */
   281   static const double SYNODIC_MONTH;
   283   //-------------------------------------------------------------------------
   284   // Constructors
   285   //-------------------------------------------------------------------------
   287   /**
   288    * Construct a new <code>CalendarAstronomer</code> object that is initialized to
   289    * the current date and time.
   290    * @internal
   291    */
   292   CalendarAstronomer();
   294   /**
   295    * Construct a new <code>CalendarAstronomer</code> object that is initialized to
   296    * the specified date and time.
   297    * @internal
   298    */
   299   CalendarAstronomer(UDate d);
   301   /**
   302    * Construct a new <code>CalendarAstronomer</code> object with the given
   303    * latitude and longitude.  The object's time is set to the current
   304    * date and time.
   305    * <p>
   306    * @param longitude The desired longitude, in <em>degrees</em> east of
   307    *                  the Greenwich meridian.
   308    *
   309    * @param latitude  The desired latitude, in <em>degrees</em>.  Positive
   310    *                  values signify North, negative South.
   311    *
   312    * @see java.util.Date#getTime()
   313    * @internal
   314    */
   315   CalendarAstronomer(double longitude, double latitude);
   317   /**
   318    * Destructor
   319    * @internal
   320    */
   321   ~CalendarAstronomer();
   323   //-------------------------------------------------------------------------
   324   // Time and date getters and setters
   325   //-------------------------------------------------------------------------
   327   /**
   328    * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
   329    * astronomical calculations are performed based on this time setting.
   330    *
   331    * @param aTime the date and time, expressed as the number of milliseconds since
   332    *              1/1/1970 0:00 GMT (Gregorian).
   333    *
   334    * @see #setDate
   335    * @see #getTime
   336    * @internal
   337    */
   338   void setTime(UDate aTime);
   341   /**
   342    * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
   343    * astronomical calculations are performed based on this time setting.
   344    *
   345    * @param aTime the date and time, expressed as the number of milliseconds since
   346    *              1/1/1970 0:00 GMT (Gregorian).
   347    *
   348    * @see #getTime
   349    * @internal
   350    */
   351   void setDate(UDate aDate) { setTime(aDate); }
   353   /**
   354    * Set the current date and time of this <code>CalendarAstronomer</code> object.  All
   355    * astronomical calculations are performed based on this time setting.
   356    *
   357    * @param jdn   the desired time, expressed as a "julian day number",
   358    *              which is the number of elapsed days since
   359    *              1/1/4713 BC (Julian), 12:00 GMT.  Note that julian day
   360    *              numbers start at <em>noon</em>.  To get the jdn for
   361    *              the corresponding midnight, subtract 0.5.
   362    *
   363    * @see #getJulianDay
   364    * @see #JULIAN_EPOCH_MS
   365    * @internal
   366    */
   367   void setJulianDay(double jdn);
   369   /**
   370    * Get the current time of this <code>CalendarAstronomer</code> object,
   371    * represented as the number of milliseconds since
   372    * 1/1/1970 AD 0:00 GMT (Gregorian).
   373    *
   374    * @see #setTime
   375    * @see #getDate
   376    * @internal
   377    */
   378   UDate getTime();
   380   /**
   381    * Get the current time of this <code>CalendarAstronomer</code> object,
   382    * expressed as a "julian day number", which is the number of elapsed
   383    * days since 1/1/4713 BC (Julian), 12:00 GMT.
   384    *
   385    * @see #setJulianDay
   386    * @see #JULIAN_EPOCH_MS
   387    * @internal
   388    */
   389   double getJulianDay();
   391   /**
   392    * Return this object's time expressed in julian centuries:
   393    * the number of centuries after 1/1/1900 AD, 12:00 GMT
   394    *
   395    * @see #getJulianDay
   396    * @internal
   397    */
   398   double getJulianCentury();
   400   /**
   401    * Returns the current Greenwich sidereal time, measured in hours
   402    * @internal
   403    */
   404   double getGreenwichSidereal();
   406 private:
   407   double getSiderealOffset();
   408 public:
   409   /**
   410    * Returns the current local sidereal time, measured in hours
   411    * @internal
   412    */
   413   double getLocalSidereal();
   415   /**
   416    * Converts local sidereal time to Universal Time.
   417    *
   418    * @param lst   The Local Sidereal Time, in hours since sidereal midnight
   419    *              on this object's current date.
   420    *
   421    * @return      The corresponding Universal Time, in milliseconds since
   422    *              1 Jan 1970, GMT.
   423    */
   424   //private:
   425   double lstToUT(double lst);
   427   /**
   428    *
   429    * Convert from ecliptic to equatorial coordinates.
   430    *
   431    * @param ecliptic     The ecliptic
   432    * @param result       Fillin result
   433    * @return reference to result
   434    */
   435   Equatorial& eclipticToEquatorial(Equatorial& result, const Ecliptic& ecliptic);
   437   /**
   438    * Convert from ecliptic to equatorial coordinates.
   439    *
   440    * @param eclipLong     The ecliptic longitude
   441    * @param eclipLat      The ecliptic latitude
   442    *
   443    * @return              The corresponding point in equatorial coordinates.
   444    * @internal
   445    */
   446   Equatorial& eclipticToEquatorial(Equatorial& result, double eclipLong, double eclipLat);
   448   /**
   449    * Convert from ecliptic longitude to equatorial coordinates.
   450    *
   451    * @param eclipLong     The ecliptic longitude
   452    *
   453    * @return              The corresponding point in equatorial coordinates.
   454    * @internal
   455    */
   456   Equatorial& eclipticToEquatorial(Equatorial& result, double eclipLong) ;
   458   /**
   459    * @internal
   460    */
   461   Horizon& eclipticToHorizon(Horizon& result, double eclipLong) ;
   463   //-------------------------------------------------------------------------
   464   // The Sun
   465   //-------------------------------------------------------------------------
   467   /**
   468    * The longitude of the sun at the time specified by this object.
   469    * The longitude is measured in radians along the ecliptic
   470    * from the "first point of Aries," the point at which the ecliptic
   471    * crosses the earth's equatorial plane at the vernal equinox.
   472    * <p>
   473    * Currently, this method uses an approximation of the two-body Kepler's
   474    * equation for the earth and the sun.  It does not take into account the
   475    * perturbations caused by the other planets, the moon, etc.
   476    * @internal
   477    */
   478   double getSunLongitude();
   480   /**
   481    * TODO Make this public when the entire class is package-private.
   482    */
   483   /*public*/ void getSunLongitude(double julianDay, double &longitude, double &meanAnomaly);
   485   /**
   486    * The position of the sun at this object's current date and time,
   487    * in equatorial coordinates.
   488    * @param result fillin for the result
   489    * @internal
   490    */
   491   Equatorial& getSunPosition(Equatorial& result);
   493 public:
   494   /**
   495    * Constant representing the vernal equinox.
   496    * For use with {@link #getSunTime getSunTime}.
   497    * Note: In this case, "vernal" refers to the northern hemisphere's seasons.
   498    * @internal
   499    */
   500 //  static double VERNAL_EQUINOX();
   502   /**
   503    * Constant representing the summer solstice.
   504    * For use with {@link #getSunTime getSunTime}.
   505    * Note: In this case, "summer" refers to the northern hemisphere's seasons.
   506    * @internal
   507    */
   508   static double SUMMER_SOLSTICE();
   510   /**
   511    * Constant representing the autumnal equinox.
   512    * For use with {@link #getSunTime getSunTime}.
   513    * Note: In this case, "autumn" refers to the northern hemisphere's seasons.
   514    * @internal
   515    */
   516 //  static double AUTUMN_EQUINOX();
   518   /**
   519    * Constant representing the winter solstice.
   520    * For use with {@link #getSunTime getSunTime}.
   521    * Note: In this case, "winter" refers to the northern hemisphere's seasons.
   522    * @internal
   523    */
   524   static double WINTER_SOLSTICE();
   526   /**
   527    * Find the next time at which the sun's ecliptic longitude will have
   528    * the desired value.
   529    * @internal
   530    */
   531   UDate getSunTime(double desired, UBool next);
   533   /**
   534    * Returns the time (GMT) of sunrise or sunset on the local date to which
   535    * this calendar is currently set.
   536    *
   537    * NOTE: This method only works well if this object is set to a
   538    * time near local noon.  Because of variations between the local
   539    * official time zone and the geographic longitude, the
   540    * computation can flop over into an adjacent day if this object
   541    * is set to a time near local midnight.
   542    *
   543    * @internal
   544    */
   545   UDate getSunRiseSet(UBool rise);
   547   //-------------------------------------------------------------------------
   548   // The Moon
   549   //-------------------------------------------------------------------------
   551   /**
   552    * The position of the moon at the time set on this
   553    * object, in equatorial coordinates.
   554    * @internal
   555    * @return const reference to internal field of calendar astronomer. Do not use outside of the lifetime of this astronomer.
   556    */
   557   const Equatorial& getMoonPosition();
   559   /**
   560    * The "age" of the moon at the time specified in this object.
   561    * This is really the angle between the
   562    * current ecliptic longitudes of the sun and the moon,
   563    * measured in radians.
   564    *
   565    * @see #getMoonPhase
   566    * @internal
   567    */
   568   double getMoonAge();
   570   /**
   571    * Calculate the phase of the moon at the time set in this object.
   572    * The returned phase is a <code>double</code> in the range
   573    * <code>0 <= phase < 1</code>, interpreted as follows:
   574    * <ul>
   575    * <li>0.00: New moon
   576    * <li>0.25: First quarter
   577    * <li>0.50: Full moon
   578    * <li>0.75: Last quarter
   579    * </ul>
   580    *
   581    * @see #getMoonAge
   582    * @internal
   583    */
   584   double getMoonPhase();
   586   class U_I18N_API MoonAge : public UMemory {
   587   public:
   588     MoonAge(double l)
   589       :  value(l) { }
   590     void set(double l) { value = l; }
   591     double value;
   592   };
   594   /**
   595    * Constant representing a new moon.
   596    * For use with {@link #getMoonTime getMoonTime}
   597    * @internal
   598    */
   599   static const MoonAge NEW_MOON();
   601   /**
   602    * Constant representing the moon's first quarter.
   603    * For use with {@link #getMoonTime getMoonTime}
   604    * @internal
   605    */
   606 //  static const MoonAge FIRST_QUARTER();
   608   /**
   609    * Constant representing a full moon.
   610    * For use with {@link #getMoonTime getMoonTime}
   611    * @internal
   612    */
   613   static const MoonAge FULL_MOON();
   615   /**
   616    * Constant representing the moon's last quarter.
   617    * For use with {@link #getMoonTime getMoonTime}
   618    * @internal
   619    */
   620 //  static const MoonAge LAST_QUARTER();
   622   /**
   623    * Find the next or previous time at which the Moon's ecliptic
   624    * longitude will have the desired value.
   625    * <p>
   626    * @param desired   The desired longitude.
   627    * @param next      <tt>true</tt> if the next occurrance of the phase
   628    *                  is desired, <tt>false</tt> for the previous occurrance.
   629    * @internal
   630    */
   631   UDate getMoonTime(double desired, UBool next);
   632   UDate getMoonTime(const MoonAge& desired, UBool next);
   634   /**
   635    * Returns the time (GMT) of sunrise or sunset on the local date to which
   636    * this calendar is currently set.
   637    * @internal
   638    */
   639   UDate getMoonRiseSet(UBool rise);
   641   //-------------------------------------------------------------------------
   642   // Interpolation methods for finding the time at which a given event occurs
   643   //-------------------------------------------------------------------------
   645   // private
   646   class AngleFunc : public UMemory {
   647   public:
   648     virtual double eval(CalendarAstronomer&) = 0;
   649     virtual ~AngleFunc();
   650   };
   651   friend class AngleFunc;
   653   UDate timeOfAngle(AngleFunc& func, double desired,
   654                     double periodDays, double epsilon, UBool next);
   656   class CoordFunc : public UMemory {
   657   public:
   658     virtual void eval(Equatorial& result, CalendarAstronomer&) = 0;
   659     virtual ~CoordFunc();
   660   };
   661   friend class CoordFunc;
   663   double riseOrSet(CoordFunc& func, UBool rise,
   664                    double diameter, double refraction,
   665                    double epsilon);
   667   //-------------------------------------------------------------------------
   668   // Other utility methods
   669   //-------------------------------------------------------------------------
   670 private:
   672   /**
   673    * Return the obliquity of the ecliptic (the angle between the ecliptic
   674    * and the earth's equator) at the current time.  This varies due to
   675    * the precession of the earth's axis.
   676    *
   677    * @return  the obliquity of the ecliptic relative to the equator,
   678    *          measured in radians.
   679    */
   680   double eclipticObliquity();
   682   //-------------------------------------------------------------------------
   683   // Private data
   684   //-------------------------------------------------------------------------
   685 private:
   686   /**
   687    * Current time in milliseconds since 1/1/1970 AD
   688    * @see java.util.Date#getTime
   689    */
   690   UDate fTime;
   692   /* These aren't used yet, but they'll be needed for sunset calculations
   693    * and equatorial to horizon coordinate conversions
   694    */
   695   double fLongitude;
   696   double fLatitude;
   697   double fGmtOffset;
   699   //
   700   // The following fields are used to cache calculated results for improved
   701   // performance.  These values all depend on the current time setting
   702   // of this object, so the clearCache method is provided.
   703   //
   705   double    julianDay;
   706   double    julianCentury;
   707   double    sunLongitude;
   708   double    meanAnomalySun;
   709   double    moonLongitude;
   710   double    moonEclipLong;
   711   double    meanAnomalyMoon;
   712   double    eclipObliquity;
   713   double    siderealT0;
   714   double    siderealTime;
   716   void clearCache();
   718   Equatorial  moonPosition;
   719   UBool       moonPositionSet;
   721   /**
   722    * @internal
   723    */
   724 //  UDate local(UDate localMillis);
   725 };
   727 U_NAMESPACE_END
   729 struct UHashtable;
   731 U_NAMESPACE_BEGIN
   733 /**
   734  * Cache of month -> julian day
   735  * @internal
   736  */
   737 class CalendarCache : public UMemory {
   738 public:
   739   static int32_t get(CalendarCache** cache, int32_t key, UErrorCode &status);
   740   static void put(CalendarCache** cache, int32_t key, int32_t value, UErrorCode &status);
   741   virtual ~CalendarCache();
   742 private:
   743   CalendarCache(int32_t size, UErrorCode& status);
   744   static void createCache(CalendarCache** cache, UErrorCode& status);
   745   /**
   746    * not implemented
   747    */
   748   CalendarCache();
   749   UHashtable *fTable;
   750 };
   752 U_NAMESPACE_END
   754 #endif
   755 #endif

mercurial