]>
Commit | Line | Data |
---|---|---|
374ca955 A |
1 | /************************************************************************ |
2 | * Copyright (C) 1996-2003, International Business Machines Corporation * | |
3 | * and others. All Rights Reserved. * | |
4 | ************************************************************************ | |
5 | * 2003-nov-07 srl Port from Java | |
6 | */ | |
7 | ||
8 | #ifndef ASTRO_H | |
9 | #define ASTRO_H | |
10 | ||
11 | #include "unicode/utypes.h" | |
12 | ||
13 | #if !UCONFIG_NO_FORMATTING | |
14 | ||
15 | #include "gregoimp.h" // for Math | |
16 | #include "unicode/unistr.h" | |
17 | ||
18 | U_NAMESPACE_BEGIN | |
19 | ||
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 | |
57 | ||
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 | } | |
89 | ||
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 | } | |
100 | ||
101 | /** | |
102 | * Return a string representation of this object | |
103 | * @internal | |
104 | */ | |
105 | UnicodeString toString() const; | |
106 | ||
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; | |
114 | ||
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 | }; | |
128 | ||
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) { } | |
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 | /** | |
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) { } | |
230 | ||
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 | } | |
241 | ||
242 | /** | |
243 | * Return a string representation of this object, with the | |
244 | * angles measured in degrees. | |
245 | * @internal | |
246 | */ | |
247 | UnicodeString toString() const; | |
248 | ||
249 | /** | |
250 | * The object's altitude above the horizon, in radians. | |
251 | * @internal | |
252 | */ | |
253 | double altitude; | |
254 | ||
255 | /** | |
256 | * The object's direction, in radians clockwise from north. | |
257 | * @internal | |
258 | */ | |
259 | double azimuth; | |
260 | }; | |
261 | ||
262 | public: | |
263 | //------------------------------------------------------------------------- | |
264 | // Assorted private data used for conversions | |
265 | //------------------------------------------------------------------------- | |
266 | ||
267 | // My own copies of these so compilers are more likely to optimize them away | |
268 | static const double PI; | |
269 | ||
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; | |
282 | ||
283 | //------------------------------------------------------------------------- | |
284 | // Constructors | |
285 | //------------------------------------------------------------------------- | |
286 | ||
287 | /** | |
288 | * Construct a new <code>CalendarAstronomer</code> object that is initialized to | |
289 | * the current date and time. | |
290 | * @internal | |
291 | */ | |
292 | CalendarAstronomer(); | |
293 | ||
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); | |
300 | ||
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); | |
316 | ||
317 | /** | |
318 | * Destructor | |
319 | * @internal | |
320 | */ | |
321 | ~CalendarAstronomer(); | |
322 | ||
323 | //------------------------------------------------------------------------- | |
324 | // Time and date getters and setters | |
325 | //------------------------------------------------------------------------- | |
326 | ||
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); | |
339 | ||
340 | ||
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); } | |
352 | ||
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); | |
368 | ||
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(); | |
379 | ||
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(); | |
390 | ||
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(); | |
399 | ||
400 | /** | |
401 | * Returns the current Greenwich sidereal time, measured in hours | |
402 | * @internal | |
403 | */ | |
404 | double getGreenwichSidereal(); | |
405 | ||
406 | private: | |
407 | double getSiderealOffset(); | |
408 | public: | |
409 | /** | |
410 | * Returns the current local sidereal time, measured in hours | |
411 | * @internal | |
412 | */ | |
413 | double getLocalSidereal(); | |
414 | ||
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); | |
426 | ||
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); | |
436 | ||
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); | |
447 | ||
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) ; | |
457 | ||
458 | /** | |
459 | * @internal | |
460 | */ | |
461 | Horizon& eclipticToHorizon(Horizon& result, double eclipLong) ; | |
462 | ||
463 | //------------------------------------------------------------------------- | |
464 | // The Sun | |
465 | //------------------------------------------------------------------------- | |
466 | ||
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(); | |
479 | ||
480 | /** | |
481 | * TODO Make this public when the entire class is package-private. | |
482 | */ | |
483 | /*public*/ void getSunLongitude(double julianDay, double &longitude, double &meanAnomaly); | |
484 | ||
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); | |
492 | ||
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(); | |
501 | ||
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(); | |
509 | ||
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(); | |
517 | ||
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(); | |
525 | ||
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); | |
532 | ||
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); | |
546 | ||
547 | //------------------------------------------------------------------------- | |
548 | // The Moon | |
549 | //------------------------------------------------------------------------- | |
550 | ||
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(); | |
558 | ||
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(); | |
569 | ||
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(); | |
585 | ||
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 | }; | |
593 | ||
594 | /** | |
595 | * Constant representing a new moon. | |
596 | * For use with {@link #getMoonTime getMoonTime} | |
597 | * @internal | |
598 | */ | |
599 | static const MoonAge NEW_MOON(); | |
600 | ||
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(); | |
607 | ||
608 | /** | |
609 | * Constant representing a full moon. | |
610 | * For use with {@link #getMoonTime getMoonTime} | |
611 | * @internal | |
612 | */ | |
613 | static const MoonAge FULL_MOON(); | |
614 | ||
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(); | |
621 | ||
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); | |
633 | ||
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); | |
640 | ||
641 | //------------------------------------------------------------------------- | |
642 | // Interpolation methods for finding the time at which a given event occurs | |
643 | //------------------------------------------------------------------------- | |
644 | ||
645 | // private | |
646 | class U_I18N_API AngleFunc : public UMemory { | |
647 | public: | |
648 | virtual double eval(CalendarAstronomer&) = 0; | |
649 | }; | |
650 | friend class AngleFunc; | |
651 | ||
652 | UDate timeOfAngle(AngleFunc& func, double desired, | |
653 | double periodDays, double epsilon, UBool next); | |
654 | ||
655 | class U_I18N_API CoordFunc : public UMemory { | |
656 | public: | |
657 | virtual void eval(Equatorial& result, CalendarAstronomer&) = 0; | |
658 | }; | |
659 | friend class CoordFunc; | |
660 | ||
661 | double riseOrSet(CoordFunc& func, UBool rise, | |
662 | double diameter, double refraction, | |
663 | double epsilon); | |
664 | ||
665 | //------------------------------------------------------------------------- | |
666 | // Other utility methods | |
667 | //------------------------------------------------------------------------- | |
668 | private: | |
669 | /*** | |
670 | * Given 'value', add or subtract 'range' until 0 <= 'value' < range. | |
671 | * The modulus operator. | |
672 | */ | |
673 | inline static double normalize(double value, double range) { | |
674 | return value - range * Math::floorDivide(value, range); | |
675 | } | |
676 | ||
677 | /** | |
678 | * Normalize an angle so that it's in the range 0 - 2pi. | |
679 | * For positive angles this is just (angle % 2pi), but the Java | |
680 | * mod operator doesn't work that way for negative numbers.... | |
681 | */ | |
682 | inline static double norm2PI(double angle) { | |
683 | return normalize(angle, CalendarAstronomer::PI * 2.0); | |
684 | } | |
685 | ||
686 | /** | |
687 | * Normalize an angle into the range -PI - PI | |
688 | */ | |
689 | inline static double normPI(double angle) { | |
690 | return normalize(angle + PI, CalendarAstronomer::PI * 2.0) - PI; | |
691 | } | |
692 | ||
693 | /** | |
694 | * Find the "true anomaly" (longitude) of an object from | |
695 | * its mean anomaly and the eccentricity of its orbit. This uses | |
696 | * an iterative solution to Kepler's equation. | |
697 | * | |
698 | * @param meanAnomaly The object's longitude calculated as if it were in | |
699 | * a regular, circular orbit, measured in radians | |
700 | * from the point of perigee. | |
701 | * | |
702 | * @param eccentricity The eccentricity of the orbit | |
703 | * | |
704 | * @return The true anomaly (longitude) measured in radians | |
705 | */ | |
706 | double trueAnomaly(double meanAnomaly, double eccentricity); | |
707 | ||
708 | /** | |
709 | * Return the obliquity of the ecliptic (the angle between the ecliptic | |
710 | * and the earth's equator) at the current time. This varies due to | |
711 | * the precession of the earth's axis. | |
712 | * | |
713 | * @return the obliquity of the ecliptic relative to the equator, | |
714 | * measured in radians. | |
715 | */ | |
716 | double eclipticObliquity(); | |
717 | ||
718 | //------------------------------------------------------------------------- | |
719 | // Private data | |
720 | //------------------------------------------------------------------------- | |
721 | private: | |
722 | /** | |
723 | * Current time in milliseconds since 1/1/1970 AD | |
724 | * @see java.util.Date#getTime | |
725 | */ | |
726 | UDate fTime; | |
727 | ||
728 | /* These aren't used yet, but they'll be needed for sunset calculations | |
729 | * and equatorial to horizon coordinate conversions | |
730 | */ | |
731 | double fLongitude; | |
732 | double fLatitude; | |
733 | double fGmtOffset; | |
734 | ||
735 | // | |
736 | // The following fields are used to cache calculated results for improved | |
737 | // performance. These values all depend on the current time setting | |
738 | // of this object, so the clearCache method is provided. | |
739 | // | |
740 | ||
741 | double julianDay ; | |
742 | double julianCentury ; | |
743 | double sunLongitude ; | |
744 | double meanAnomalySun ; | |
745 | double moonLongitude ; | |
746 | double moonEclipLong ; | |
747 | double meanAnomalyMoon ; | |
748 | double eclipObliquity ; | |
749 | double siderealT0 ; | |
750 | double siderealTime ; | |
751 | ||
752 | void clearCache(); | |
753 | ||
754 | Equatorial moonPosition; | |
755 | UBool moonPositionSet; | |
756 | ||
757 | /** | |
758 | * @internal | |
759 | */ | |
760 | UDate local(UDate localMillis); | |
761 | }; | |
762 | ||
763 | U_NAMESPACE_END | |
764 | ||
765 | struct UHashtable; | |
766 | ||
767 | U_NAMESPACE_BEGIN | |
768 | ||
769 | /** | |
770 | * Cache of month -> julian day | |
771 | * @internal | |
772 | */ | |
773 | class U_I18N_API CalendarCache : public UMemory { | |
774 | public: | |
775 | static int32_t get(CalendarCache** cache, int32_t key, UErrorCode &status); | |
776 | static void put(CalendarCache** cache, int32_t key, int32_t value, UErrorCode &status); | |
777 | virtual ~CalendarCache(); | |
778 | private: | |
779 | CalendarCache(int32_t size, UErrorCode& status); | |
780 | static void createCache(CalendarCache** cache, UErrorCode& status); | |
781 | /** | |
782 | * not implemented | |
783 | */ | |
784 | CalendarCache(); | |
785 | UHashtable *fTable; | |
786 | }; | |
787 | ||
788 | U_NAMESPACE_END | |
789 | ||
790 | #endif | |
791 | #endif |