line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Astro::MoonPhase; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
112192
|
use strict; |
|
3
|
|
|
|
|
8
|
|
|
3
|
|
|
|
|
140
|
|
4
|
3
|
|
|
3
|
|
17
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK); |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
471
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
require Exporter; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
9
|
|
|
|
|
|
|
@EXPORT = qw(phase phasehunt phaselist); |
10
|
|
|
|
|
|
|
$VERSION = '0.60'; |
11
|
|
|
|
|
|
|
|
12
|
3
|
|
|
|
|
11148
|
use vars qw ( |
13
|
|
|
|
|
|
|
$Epoch |
14
|
|
|
|
|
|
|
$Elonge $Elongp $Eccent $Sunsmax $Sunangsiz |
15
|
|
|
|
|
|
|
$Mmlong $Mmlongp $Mlnode $Minc $Mecc $Mangsiz $Msmax $Mparallax $Synmonth |
16
|
|
|
|
|
|
|
$Pi |
17
|
3
|
|
|
3
|
|
17
|
); |
|
3
|
|
|
|
|
9
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# Astronomical constants. |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
$Epoch = 2444238.5; # 1980 January 0.0 |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Constants defining the Sun's apparent orbit. |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
$Elonge = 278.833540; # ecliptic longitude of the Sun at epoch 1980.0 |
26
|
|
|
|
|
|
|
$Elongp = 282.596403; # ecliptic longitude of the Sun at perigee |
27
|
|
|
|
|
|
|
$Eccent = 0.016718; # eccentricity of Earth's orbit |
28
|
|
|
|
|
|
|
$Sunsmax = 1.495985e8; # semi-major axis of Earth's orbit, km |
29
|
|
|
|
|
|
|
$Sunangsiz = 0.533128; # sun's angular size, degrees, at semi-major axis distance |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# Elements of the Moon's orbit, epoch 1980.0. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
$Mmlong = 64.975464; # moon's mean longitude at the epoch |
34
|
|
|
|
|
|
|
$Mmlongp = 349.383063; # mean longitude of the perigee at the epoch |
35
|
|
|
|
|
|
|
$Mlnode = 151.950429; # mean longitude of the node at the epoch |
36
|
|
|
|
|
|
|
$Minc = 5.145396; # inclination of the Moon's orbit |
37
|
|
|
|
|
|
|
$Mecc = 0.054900; # eccentricity of the Moon's orbit |
38
|
|
|
|
|
|
|
$Mangsiz = 0.5181; # moon's angular size at distance a from Earth |
39
|
|
|
|
|
|
|
$Msmax = 384401.0; # semi-major axis of Moon's orbit in km |
40
|
|
|
|
|
|
|
$Mparallax = 0.9507; # parallax at distance a from Earth |
41
|
|
|
|
|
|
|
$Synmonth = 29.53058868; # synodic month (new Moon to new Moon) |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# Properties of the Earth. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
$Pi = 3.14159265358979323846; # assume not near black hole nor in Tennessee |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# Handy mathematical functions. |
48
|
|
|
|
|
|
|
|
49
|
0
|
0
|
|
0
|
0
|
0
|
sub sgn { return (($_[0] < 0) ? -1 : ($_[0] > 0 ? 1 : 0)); } # extract sign |
|
|
0
|
|
|
|
|
|
50
|
0
|
|
|
0
|
0
|
0
|
sub fixangle { return ($_[0] - 360.0 * (floor($_[0] / 360.0))); } # fix angle |
51
|
8343
|
|
|
8343
|
0
|
28444
|
sub torad { return ($_[0] * ($Pi / 180.0)); } # deg->rad |
52
|
0
|
|
|
0
|
0
|
0
|
sub todeg { return ($_[0] * (180.0 / $Pi)); } # rad->deg |
53
|
7841
|
|
|
7841
|
0
|
15368
|
sub dsin { return (sin(torad($_[0]))); } # sin from deg |
54
|
502
|
|
|
502
|
0
|
788
|
sub dcos { return (cos(torad($_[0]))); } # cos from deg |
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
0
|
0
|
0
|
sub tan { return sin($_[0])/cos($_[0]); } |
57
|
0
|
0
|
0
|
0
|
0
|
0
|
sub asin { return ($_[0]<-1 or $_[0]>1) ? undef : atan2($_[0],sqrt(1-$_[0]*$_[0])); } |
58
|
|
|
|
|
|
|
sub atan { |
59
|
0
|
0
|
|
0
|
0
|
0
|
if ($_[0]==0) { return 0; } |
|
0
|
0
|
|
|
|
0
|
|
60
|
0
|
|
|
|
|
0
|
elsif ($_[0]>0) { return atan2(sqrt(1+$_[0]*$_[0]),sqrt(1+1/($_[0]*$_[0]))); } |
61
|
0
|
|
|
|
|
0
|
else { return -atan2(sqrt(1+$_[0]*$_[0]),sqrt(1+1/($_[0]*$_[0]))); } |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub floor { |
65
|
184
|
|
|
184
|
0
|
219
|
my $val = shift; |
66
|
184
|
|
|
|
|
244
|
my $neg = $val < 0; |
67
|
184
|
|
|
|
|
215
|
my $asint = int($val); |
68
|
184
|
|
|
|
|
227
|
my $exact = $val == $asint; |
69
|
|
|
|
|
|
|
|
70
|
184
|
50
|
|
|
|
724
|
return ($exact ? $asint : $neg ? $asint - 1 : $asint); |
|
|
100
|
|
|
|
|
|
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# jtime - convert internal date and time to astronomical Julian |
76
|
|
|
|
|
|
|
# time (i.e. Julian date plus day fraction) |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub jtime { |
80
|
|
|
|
|
|
|
|
81
|
32
|
|
|
32
|
0
|
54
|
my $t = shift; |
82
|
32
|
|
|
|
|
46
|
my ($julian); |
83
|
32
|
|
|
|
|
205
|
$julian = ($t / 86400) + 2440587.5; # (seconds /(seconds per day)) + julian date of epoch |
84
|
32
|
|
|
|
|
167
|
return ($julian); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# jdaytosecs - convert Julian date to a UNIX epoch |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub jdaytosecs { |
92
|
441
|
|
|
441
|
0
|
597
|
my $jday = shift; |
93
|
441
|
|
|
|
|
428
|
my $stamp; |
94
|
|
|
|
|
|
|
|
95
|
441
|
|
|
|
|
529
|
$stamp = ($jday - 2440587.5)*86400; # (juliandate - jdate of unix epoch)*(seconds per julian day) |
96
|
441
|
|
|
|
|
1019
|
return($stamp); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# jyear - convert Julian date to year, month, day, which are |
103
|
|
|
|
|
|
|
# returned via integer pointers to integers |
104
|
|
|
|
|
|
|
sub jyear { |
105
|
|
|
|
|
|
|
|
106
|
23
|
|
|
23
|
0
|
60
|
my ($td, $yy, $mm, $dd) = @_; |
107
|
23
|
|
|
|
|
45
|
my ($z, $f, $a, $alpha, $b, $c, $d, $e); |
108
|
|
|
|
|
|
|
|
109
|
23
|
|
|
|
|
43
|
$td += 0.5; # astronomical to civil |
110
|
23
|
|
|
|
|
223
|
$z = floor($td); |
111
|
23
|
|
|
|
|
43
|
$f = $td - $z; |
112
|
|
|
|
|
|
|
|
113
|
23
|
50
|
|
|
|
52
|
if ($z < 2299161.0) { |
114
|
0
|
|
|
|
|
0
|
$a = $z; |
115
|
|
|
|
|
|
|
} else { |
116
|
23
|
|
|
|
|
55
|
$alpha = floor(($z - 1867216.25) / 36524.25); |
117
|
23
|
|
|
|
|
70
|
$a = $z + 1 + $alpha - floor($alpha / 4); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
|
121
|
23
|
|
|
|
|
594
|
$b = $a + 1524; |
122
|
23
|
|
|
|
|
714
|
$c = floor(($b - 122.1) / 365.25); |
123
|
23
|
|
|
|
|
61
|
$d = floor(365.25 * $c); |
124
|
23
|
|
|
|
|
55
|
$e = floor(($b - $d) / 30.6001); |
125
|
|
|
|
|
|
|
|
126
|
23
|
|
|
|
|
56
|
$$dd = $b - $d - floor(30.6001 * $e) + $f; |
127
|
23
|
100
|
|
|
|
57
|
$$mm = $e < 14 ? $e - 1 : $e - 13; |
128
|
23
|
100
|
|
|
|
296
|
$$yy = $$mm > 2 ? $c - 4716 : $c - 4715; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
## meanphase -- Calculates time of the mean new Moon for a given |
133
|
|
|
|
|
|
|
## base date. This argument K to this function is the |
134
|
|
|
|
|
|
|
## precomputed synodic month index, given by: |
135
|
|
|
|
|
|
|
## |
136
|
|
|
|
|
|
|
## K = (year - 1900) * 12.3685 |
137
|
|
|
|
|
|
|
## |
138
|
|
|
|
|
|
|
## where year is expressed as a year and fractional year. |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub meanphase { |
142
|
59
|
|
|
59
|
0
|
79
|
my ($sdate, $k) = @_; |
143
|
59
|
|
|
|
|
71
|
my ($t, $t2, $t3, $nt1); |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
## Time in Julian centuries from 1900 January 0.5 |
146
|
59
|
|
|
|
|
91
|
$t = ($sdate - 2415020.0) / 36525; |
147
|
59
|
|
|
|
|
73
|
$t2 = $t * $t; ## Square for frequent use |
148
|
59
|
|
|
|
|
67
|
$t3 = $t2 * $t; ## Cube for frequent use |
149
|
|
|
|
|
|
|
|
150
|
59
|
|
|
|
|
167
|
$nt1 = 2415020.75933 + $Synmonth * $k |
151
|
|
|
|
|
|
|
+ 0.0001178 * $t2 |
152
|
|
|
|
|
|
|
- 0.000000155 * $t3 |
153
|
|
|
|
|
|
|
+ 0.00033 * dsin(166.56 + 132.87 * $t - 0.009173 * $t2); |
154
|
|
|
|
|
|
|
|
155
|
59
|
|
|
|
|
105
|
return ($nt1); |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# truephase - given a K value used to determine the mean phase of the |
160
|
|
|
|
|
|
|
# new moon, and a phase selector (0.0, 0.25, 0.5, 0.75), |
161
|
|
|
|
|
|
|
# obtain the true, corrected phase time |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub truephase { |
164
|
520
|
|
|
520
|
0
|
1057
|
my ($k, $phase) = @_; |
165
|
520
|
|
|
|
|
795
|
my ($t, $t2, $t3, $pt, $m, $mprime, $f); |
166
|
520
|
|
|
|
|
695
|
my $apcor = 0; |
167
|
|
|
|
|
|
|
|
168
|
520
|
|
|
|
|
630
|
$k += $phase; # add phase to new moon time |
169
|
520
|
|
|
|
|
544
|
$t = $k / 1236.85; # time in Julian centuries from |
170
|
|
|
|
|
|
|
# 1900 January 0.5 |
171
|
520
|
|
|
|
|
939
|
$t2 = $t * $t; # square for frequent use |
172
|
520
|
|
|
|
|
825
|
$t3 = $t2 * $t; # cube for frequent use |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# mean time of phase */ |
175
|
520
|
|
|
|
|
1689
|
$pt = 2415020.75933 |
176
|
|
|
|
|
|
|
+ $Synmonth * $k |
177
|
|
|
|
|
|
|
+ 0.0001178 * $t2 |
178
|
|
|
|
|
|
|
- 0.000000155 * $t3 |
179
|
|
|
|
|
|
|
+ 0.00033 * dsin(166.56 + 132.87 * $t - 0.009173 * $t2); |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# Sun's mean anomaly |
182
|
520
|
|
|
|
|
932
|
$m = 359.2242 |
183
|
|
|
|
|
|
|
+ 29.10535608 * $k |
184
|
|
|
|
|
|
|
- 0.0000333 * $t2 |
185
|
|
|
|
|
|
|
- 0.00000347 * $t3; |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Moon's mean anomaly |
188
|
520
|
|
|
|
|
741
|
$mprime = 306.0253 |
189
|
|
|
|
|
|
|
+ 385.81691806 * $k |
190
|
|
|
|
|
|
|
+ 0.0107306 * $t2 |
191
|
|
|
|
|
|
|
+ 0.00001236 * $t3; |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# Moon's argument of latitude |
194
|
520
|
|
|
|
|
819
|
$f = 21.2964 |
195
|
|
|
|
|
|
|
+ 390.67050646 * $k |
196
|
|
|
|
|
|
|
- 0.0016528 * $t2 |
197
|
|
|
|
|
|
|
- 0.00000239 * $t3; |
198
|
|
|
|
|
|
|
|
199
|
520
|
100
|
100
|
|
|
3382
|
if (($phase < 0.01) || (abs($phase - 0.5) < 0.01)) { |
|
|
50
|
66
|
|
|
|
|
200
|
|
|
|
|
|
|
# Corrections for New and Full Moon. |
201
|
|
|
|
|
|
|
|
202
|
269
|
|
|
|
|
602
|
$pt += (0.1734 - 0.000393 * $t) * dsin($m) |
203
|
|
|
|
|
|
|
+ 0.0021 * dsin(2 * $m) |
204
|
|
|
|
|
|
|
- 0.4068 * dsin($mprime) |
205
|
|
|
|
|
|
|
+ 0.0161 * dsin(2 * $mprime) |
206
|
|
|
|
|
|
|
- 0.0004 * dsin(3 * $mprime) |
207
|
|
|
|
|
|
|
+ 0.0104 * dsin(2 * $f) |
208
|
|
|
|
|
|
|
- 0.0051 * dsin($m + $mprime) |
209
|
|
|
|
|
|
|
- 0.0074 * dsin($m - $mprime) |
210
|
|
|
|
|
|
|
+ 0.0004 * dsin(2 * $f + $m) |
211
|
|
|
|
|
|
|
- 0.0004 * dsin(2 * $f - $m) |
212
|
|
|
|
|
|
|
- 0.0006 * dsin(2 * $f + $mprime) |
213
|
|
|
|
|
|
|
+ 0.0010 * dsin(2 * $f - $mprime) |
214
|
|
|
|
|
|
|
+ 0.0005 * dsin($m + 2 * $mprime); |
215
|
269
|
|
|
|
|
739
|
$apcor = 1; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
elsif ((abs($phase - 0.25) < 0.01 || (abs($phase - 0.75) < 0.01))) { |
218
|
251
|
|
|
|
|
743
|
$pt += (0.1721 - 0.0004 * $t) * dsin($m) |
219
|
|
|
|
|
|
|
+ 0.0021 * dsin(2 * $m) |
220
|
|
|
|
|
|
|
- 0.6280 * dsin($mprime) |
221
|
|
|
|
|
|
|
+ 0.0089 * dsin(2 * $mprime) |
222
|
|
|
|
|
|
|
- 0.0004 * dsin(3 * $mprime) |
223
|
|
|
|
|
|
|
+ 0.0079 * dsin(2 * $f) |
224
|
|
|
|
|
|
|
- 0.0119 * dsin($m + $mprime) |
225
|
|
|
|
|
|
|
- 0.0047 * dsin($m - $mprime) |
226
|
|
|
|
|
|
|
+ 0.0003 * dsin(2 * $f + $m) |
227
|
|
|
|
|
|
|
- 0.0004 * dsin(2 * $f - $m) |
228
|
|
|
|
|
|
|
- 0.0006 * dsin(2 * $f + $mprime) |
229
|
|
|
|
|
|
|
+ 0.0021 * dsin(2 * $f - $mprime) |
230
|
|
|
|
|
|
|
+ 0.0003 * dsin($m + 2 * $mprime) |
231
|
|
|
|
|
|
|
+ 0.0004 * dsin($m - 2 * $mprime) |
232
|
|
|
|
|
|
|
- 0.0003 * dsin(2 * $m + $mprime); |
233
|
251
|
100
|
|
|
|
1493
|
if ($phase < 0.5) { |
234
|
|
|
|
|
|
|
# First quarter correction. |
235
|
128
|
|
|
|
|
282
|
$pt += 0.0028 - 0.0004 * dcos($m) + 0.0003 * dcos($mprime); |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
else { |
238
|
|
|
|
|
|
|
# Last quarter correction. |
239
|
123
|
|
|
|
|
201
|
$pt += -0.0028 + 0.0004 * dcos($m) - 0.0003 * dcos($mprime); |
240
|
|
|
|
|
|
|
} |
241
|
251
|
|
|
|
|
373
|
$apcor = 1; |
242
|
|
|
|
|
|
|
} |
243
|
520
|
50
|
|
|
|
1172
|
if (!$apcor) { |
244
|
0
|
|
|
|
|
0
|
die "truephase() called with invalid phase selector ($phase).\n"; |
245
|
|
|
|
|
|
|
} |
246
|
520
|
|
|
|
|
1000
|
return ($pt); |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
# phasehunt - find time of phases of the moon which surround the current |
250
|
|
|
|
|
|
|
# date. Five phases are found, starting and ending with the |
251
|
|
|
|
|
|
|
# new moons which bound the current lunation |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
sub phasehunt { |
254
|
14
|
|
33
|
14
|
1
|
31574
|
my $sdate = jtime(shift || time()); |
255
|
14
|
|
|
|
|
18
|
my ($adate, $k1, $k2, $nt1, $nt2); |
256
|
0
|
|
|
|
|
0
|
my ($yy, $mm, $dd); |
257
|
|
|
|
|
|
|
|
258
|
14
|
|
|
|
|
22
|
$adate = $sdate - 45; |
259
|
|
|
|
|
|
|
|
260
|
14
|
|
|
|
|
50
|
jyear($adate, \$yy, \$mm, \$dd); |
261
|
14
|
|
|
|
|
57
|
$k1 = floor(($yy + (($mm - 1) * (1.0 / 12.0)) - 1900) * 12.3685); |
262
|
|
|
|
|
|
|
|
263
|
14
|
|
|
|
|
30
|
$adate = $nt1 = meanphase($adate, $k1); |
264
|
|
|
|
|
|
|
|
265
|
14
|
|
|
|
|
20
|
while (1) { |
266
|
45
|
|
|
|
|
53
|
$adate += $Synmonth; |
267
|
45
|
|
|
|
|
58
|
$k2 = $k1 + 1; |
268
|
45
|
|
|
|
|
78
|
$nt2 = meanphase($adate, $k2); |
269
|
45
|
100
|
66
|
|
|
208
|
if (($nt1 <= $sdate) && ($nt2 > $sdate)) { |
270
|
14
|
|
|
|
|
22
|
last; |
271
|
|
|
|
|
|
|
} |
272
|
31
|
|
|
|
|
107
|
$nt1 = $nt2; |
273
|
31
|
|
|
|
|
40
|
$k1 = $k2; |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
return ( |
280
|
14
|
|
|
|
|
27
|
jdaytosecs(truephase($k1, 0.0)), |
281
|
|
|
|
|
|
|
jdaytosecs(truephase($k1, 0.25)), |
282
|
|
|
|
|
|
|
jdaytosecs(truephase($k1, 0.5)), |
283
|
|
|
|
|
|
|
jdaytosecs(truephase($k1, 0.75)), |
284
|
|
|
|
|
|
|
jdaytosecs(truephase($k2, 0.0)) |
285
|
|
|
|
|
|
|
); |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
# phaselist - find time of phases of the moon between two dates |
291
|
|
|
|
|
|
|
# times (in & out) are seconds_since_1970 |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub phaselist |
294
|
|
|
|
|
|
|
{ |
295
|
9
|
|
|
9
|
1
|
308919
|
my ($sdate, $edate) = map { jtime($_) } @_; |
|
18
|
|
|
|
|
230
|
|
296
|
|
|
|
|
|
|
|
297
|
9
|
|
|
|
|
20
|
my (@phases, $d, $k, $yy, $mm); |
298
|
|
|
|
|
|
|
|
299
|
9
|
|
|
|
|
49
|
jyear($sdate, \$yy, \$mm, \$d); |
300
|
9
|
|
|
|
|
57
|
$k = floor(($yy + (($mm - 1) * (1.0 / 12.0)) - 1900) * 12.3685) - 2; |
301
|
|
|
|
|
|
|
|
302
|
9
|
|
|
|
|
26
|
while (1) { |
303
|
117
|
|
|
|
|
163
|
++$k; |
304
|
117
|
|
|
|
|
168
|
for my $phase (0.0, 0.25, 0.5, 0.75) { |
305
|
450
|
|
|
|
|
1057
|
$d = truephase($k, $phase); |
306
|
|
|
|
|
|
|
|
307
|
450
|
100
|
|
|
|
1335
|
return @phases if $d >= $edate; |
308
|
|
|
|
|
|
|
|
309
|
441
|
100
|
|
|
|
1032
|
if ($d >= $sdate) { |
310
|
371
|
100
|
|
|
|
700
|
push @phases, int(4 * $phase) unless @phases; |
311
|
371
|
|
|
|
|
1106
|
push @phases, jdaytosecs($d); |
312
|
|
|
|
|
|
|
} # end if date should be listed |
313
|
|
|
|
|
|
|
} # end for each $phase |
314
|
|
|
|
|
|
|
} # end while 1 |
315
|
|
|
|
|
|
|
} # end phaselist |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
# kepler - solve the equation of Kepler |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
sub kepler { |
322
|
0
|
|
|
0
|
0
|
|
my ($m, $ecc) = @_; |
323
|
0
|
|
|
|
|
|
my ($e, $delta); |
324
|
0
|
|
|
|
|
|
my $EPSILON = 1e-6; |
325
|
|
|
|
|
|
|
|
326
|
0
|
|
|
|
|
|
$m = torad($m); |
327
|
0
|
|
|
|
|
|
$e = $m; |
328
|
0
|
|
|
|
|
|
do { |
329
|
0
|
|
|
|
|
|
$delta = $e - $ecc * sin($e) - $m; |
330
|
0
|
|
|
|
|
|
$e -= $delta / (1 - $ecc * cos($e)); |
331
|
|
|
|
|
|
|
} while (abs($delta) > $EPSILON); |
332
|
0
|
|
|
|
|
|
return ($e); |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# phase - calculate phase of moon as a fraction: |
338
|
|
|
|
|
|
|
# |
339
|
|
|
|
|
|
|
# The argument is the time for which the phase is requested, |
340
|
|
|
|
|
|
|
# expressed as a Julian date and fraction. Returns the terminator |
341
|
|
|
|
|
|
|
# phase angle as a percentage of a full circle (i.e., 0 to 1), |
342
|
|
|
|
|
|
|
# and stores into pointer arguments the illuminated fraction of |
343
|
|
|
|
|
|
|
# the Moon's disc, the Moon's age in days and fraction, the |
344
|
|
|
|
|
|
|
# distance of the Moon from the centre of the Earth, and the |
345
|
|
|
|
|
|
|
# angular diameter subtended by the Moon as seen by an observer |
346
|
|
|
|
|
|
|
# at the centre of the Earth. |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
sub phase { |
349
|
0
|
|
0
|
0
|
1
|
|
my $pdate = jtime(shift || time()); |
350
|
|
|
|
|
|
|
|
351
|
0
|
|
|
|
|
|
my $pphase; # illuminated fraction |
352
|
|
|
|
|
|
|
my $mage; # age of moon in days |
353
|
0
|
|
|
|
|
|
my $dist; # distance in kilometres |
354
|
0
|
|
|
|
|
|
my $angdia; # angular diameter in degrees |
355
|
0
|
|
|
|
|
|
my $sudist; # distance to Sun |
356
|
0
|
|
|
|
|
|
my $suangdia; # sun's angular diameter |
357
|
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
|
my ($Day, $N, $M, $Ec, $Lambdasun, $ml, $MM, $MN, $Ev, $Ae, $A3, $MmP, |
359
|
|
|
|
|
|
|
$mEc, $A4, $lP, $V, $lPP, $NP, $y, $x, $Lambdamoon, $BetaM, |
360
|
|
|
|
|
|
|
$MoonAge, $MoonPhase, |
361
|
|
|
|
|
|
|
$MoonDist, $MoonDFrac, $MoonAng, $MoonPar, |
362
|
|
|
|
|
|
|
$F, $SunDist, $SunAng, |
363
|
|
|
|
|
|
|
$mpfrac); |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
# Calculation of the Sun's position. |
366
|
|
|
|
|
|
|
|
367
|
0
|
|
|
|
|
|
$Day = $pdate - $Epoch; # date within epoch |
368
|
0
|
|
|
|
|
|
$N = fixangle((360 / 365.2422) * $Day); # mean anomaly of the Sun |
369
|
0
|
|
|
|
|
|
$M = fixangle($N + $Elonge - $Elongp); # convert from perigee |
370
|
|
|
|
|
|
|
# co-ordinates to epoch 1980.0 |
371
|
0
|
|
|
|
|
|
$Ec = kepler($M, $Eccent); # solve equation of Kepler |
372
|
0
|
|
|
|
|
|
$Ec = sqrt((1 + $Eccent) / (1 - $Eccent)) * tan($Ec / 2); |
373
|
0
|
|
|
|
|
|
$Ec = 2 * todeg(atan($Ec)); # true anomaly |
374
|
0
|
|
|
|
|
|
$Lambdasun = fixangle($Ec + $Elongp); # Sun's geocentric ecliptic |
375
|
|
|
|
|
|
|
# longitude |
376
|
|
|
|
|
|
|
# Orbital distance factor. |
377
|
0
|
|
|
|
|
|
$F = ((1 + $Eccent * cos(torad($Ec))) / (1 - $Eccent * $Eccent)); |
378
|
0
|
|
|
|
|
|
$SunDist = $Sunsmax / $F; # distance to Sun in km |
379
|
0
|
|
|
|
|
|
$SunAng = $F * $Sunangsiz; # Sun's angular size in degrees |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
# Calculation of the Moon's position. |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
# Moon's mean longitude. |
385
|
0
|
|
|
|
|
|
$ml = fixangle(13.1763966 * $Day + $Mmlong); |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
# Moon's mean anomaly. |
388
|
0
|
|
|
|
|
|
$MM = fixangle($ml - 0.1114041 * $Day - $Mmlongp); |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# Moon's ascending node mean longitude. |
391
|
0
|
|
|
|
|
|
$MN = fixangle($Mlnode - 0.0529539 * $Day); |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
# Evection. |
394
|
0
|
|
|
|
|
|
$Ev = 1.2739 * sin(torad(2 * ($ml - $Lambdasun) - $MM)); |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
# Annual equation. |
397
|
0
|
|
|
|
|
|
$Ae = 0.1858 * sin(torad($M)); |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
# Correction term. |
400
|
0
|
|
|
|
|
|
$A3 = 0.37 * sin(torad($M)); |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
# Corrected anomaly. |
403
|
0
|
|
|
|
|
|
$MmP = $MM + $Ev - $Ae - $A3; |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
# Correction for the equation of the centre. |
406
|
0
|
|
|
|
|
|
$mEc = 6.2886 * sin(torad($MmP)); |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
# Another correction term. |
409
|
0
|
|
|
|
|
|
$A4 = 0.214 * sin(torad(2 * $MmP)); |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# Corrected longitude. |
412
|
0
|
|
|
|
|
|
$lP = $ml + $Ev + $mEc - $Ae + $A4; |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
# Variation. |
415
|
0
|
|
|
|
|
|
$V = 0.6583 * sin(torad(2 * ($lP - $Lambdasun))); |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
# True longitude. |
418
|
0
|
|
|
|
|
|
$lPP = $lP + $V; |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
# Corrected longitude of the node. |
421
|
0
|
|
|
|
|
|
$NP = $MN - 0.16 * sin(torad($M)); |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
# Y inclination coordinate. |
424
|
0
|
|
|
|
|
|
$y = sin(torad($lPP - $NP)) * cos(torad($Minc)); |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
# X inclination coordinate. |
427
|
0
|
|
|
|
|
|
$x = cos(torad($lPP - $NP)); |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
# Ecliptic longitude. |
430
|
0
|
|
|
|
|
|
$Lambdamoon = todeg(atan2($y, $x)); |
431
|
0
|
|
|
|
|
|
$Lambdamoon += $NP; |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
# Ecliptic latitude. |
434
|
0
|
|
|
|
|
|
$BetaM = todeg(asin(sin(torad($lPP - $NP)) * sin(torad($Minc)))); |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
# Calculation of the phase of the Moon. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
# Age of the Moon in degrees. |
439
|
0
|
|
|
|
|
|
$MoonAge = $lPP - $Lambdasun; |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
# Phase of the Moon. |
442
|
0
|
|
|
|
|
|
$MoonPhase = (1 - cos(torad($MoonAge))) / 2; |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
# Calculate distance of moon from the centre of the Earth. |
445
|
|
|
|
|
|
|
|
446
|
0
|
|
|
|
|
|
$MoonDist = ($Msmax * (1 - $Mecc * $Mecc)) / |
447
|
|
|
|
|
|
|
(1 + $Mecc * cos(torad($MmP + $mEc))); |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# Calculate Moon's angular diameter. |
450
|
|
|
|
|
|
|
|
451
|
0
|
|
|
|
|
|
$MoonDFrac = $MoonDist / $Msmax; |
452
|
0
|
|
|
|
|
|
$MoonAng = $Mangsiz / $MoonDFrac; |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
# Calculate Moon's parallax. |
455
|
|
|
|
|
|
|
|
456
|
0
|
|
|
|
|
|
$MoonPar = $Mparallax / $MoonDFrac; |
457
|
|
|
|
|
|
|
|
458
|
0
|
|
|
|
|
|
$pphase = $MoonPhase; |
459
|
0
|
|
|
|
|
|
$mage = $Synmonth * (fixangle($MoonAge) / 360.0); |
460
|
0
|
|
|
|
|
|
$dist = $MoonDist; |
461
|
0
|
|
|
|
|
|
$angdia = $MoonAng; |
462
|
0
|
|
|
|
|
|
$sudist = $SunDist; |
463
|
0
|
|
|
|
|
|
$suangdia = $SunAng; |
464
|
0
|
|
|
|
|
|
$mpfrac = fixangle($MoonAge) / 360.0; |
465
|
0
|
0
|
|
|
|
|
return wantarray ? ( $mpfrac, $pphase, $mage, $dist, $angdia, $sudist,$suangdia ) : $mpfrac; |
466
|
|
|
|
|
|
|
} |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
1; |
469
|
|
|
|
|
|
|
__END__ |