| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Astro::Montenbruck::RiseSet; |
|
2
|
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
2491
|
use strict; |
|
|
3
|
|
|
|
|
30
|
|
|
|
3
|
|
|
|
|
81
|
|
|
4
|
3
|
|
|
3
|
|
13
|
use warnings; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
84
|
|
|
5
|
3
|
|
|
3
|
|
12
|
no warnings qw/experimental/; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
106
|
|
|
6
|
3
|
|
|
3
|
|
14
|
use feature qw/switch/; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
282
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
3
|
|
|
3
|
|
17
|
use Exporter qw/import/; |
|
|
3
|
|
|
|
|
5
|
|
|
|
3
|
|
|
|
|
90
|
|
|
9
|
3
|
|
|
3
|
|
20
|
use Readonly; |
|
|
3
|
|
|
|
|
21
|
|
|
|
3
|
|
|
|
|
128
|
|
|
10
|
3
|
|
|
3
|
|
1641
|
use Memoize; |
|
|
3
|
|
|
|
|
6567
|
|
|
|
3
|
|
|
|
|
193
|
|
|
11
|
|
|
|
|
|
|
memoize qw/_get_obliquity/; |
|
12
|
|
|
|
|
|
|
|
|
13
|
3
|
|
|
3
|
|
22
|
use Math::Trig qw/:pi deg2rad/; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
368
|
|
|
14
|
3
|
|
|
3
|
|
17
|
use Astro::Montenbruck::MathUtils qw/frac/; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
103
|
|
|
15
|
3
|
|
|
3
|
|
1439
|
use Astro::Montenbruck::Time qw/jd_cent/; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
237
|
|
|
16
|
3
|
|
|
3
|
|
1374
|
use Astro::Montenbruck::CoCo qw/ecl2equ/; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
165
|
|
|
17
|
3
|
|
|
3
|
|
1175
|
use Astro::Montenbruck::NutEqu qw/obliquity/; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
148
|
|
|
18
|
3
|
|
|
3
|
|
1158
|
use Astro::Montenbruck::Ephemeris qw/iterator/; |
|
|
3
|
|
|
|
|
9
|
|
|
|
3
|
|
|
|
|
154
|
|
|
19
|
3
|
|
|
3
|
|
18
|
use Astro::Montenbruck::Ephemeris::Planet qw/:ids/; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
327
|
|
|
20
|
|
|
|
|
|
|
use Astro::Montenbruck::RiseSet::Constants |
|
21
|
3
|
|
|
3
|
|
922
|
qw/:altitudes :twilight :events :states/; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
542
|
|
|
22
|
3
|
|
|
3
|
|
1298
|
use Astro::Montenbruck::RiseSet::Plarise qw/rst_func/; |
|
|
3
|
|
|
|
|
8
|
|
|
|
3
|
|
|
|
|
160
|
|
|
23
|
3
|
|
|
3
|
|
1308
|
use Astro::Montenbruck::RiseSet::Sunset qw/riseset_func/; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
3688
|
|
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
our %EXPORT_TAGS = ( all => [qw/rst riseset twilight/], ); |
|
26
|
|
|
|
|
|
|
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); |
|
27
|
|
|
|
|
|
|
our $VERSION = 0.02; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Readonly::Array our @TWILIGHT_TYPES => |
|
30
|
|
|
|
|
|
|
( $TWILIGHT_ASTRO, $TWILIGHT_NAUTICAL, $TWILIGHT_CIVIL ); |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub _get_obliquity { obliquity( $_[0] ) } |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub _get_equatorial { |
|
35
|
674
|
|
|
674
|
|
3625
|
my ( $id, $jd ) = @_; |
|
36
|
674
|
|
|
|
|
4251
|
my $t = jd_cent($jd); |
|
37
|
674
|
|
|
|
|
2552
|
my $iter = iterator( $t, [$id] ); |
|
38
|
674
|
|
|
|
|
1861
|
my $res = $iter->(); |
|
39
|
674
|
|
|
|
|
10590
|
my @ecl = @{ $res->[1] }[ 0 .. 1 ]; |
|
|
674
|
|
|
|
|
1865
|
|
|
40
|
674
|
|
|
|
|
20685
|
map { deg2rad($_) } ecl2equ( @ecl, _get_obliquity($t) ); |
|
|
1348
|
|
|
|
|
8281
|
|
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub twilight { |
|
44
|
|
|
|
|
|
|
my %arg = ( |
|
45
|
|
|
|
|
|
|
type => $TWILIGHT_NAUTICAL, |
|
46
|
|
|
|
0
|
|
|
on_event => sub { }, |
|
47
|
|
|
|
0
|
|
|
on_noevent => sub { }, |
|
48
|
|
|
|
|
|
|
@_ |
|
49
|
11
|
|
|
11
|
1
|
9464
|
); |
|
50
|
11
|
|
|
|
|
120
|
my $type = delete $arg{type}; |
|
51
|
11
|
50
|
|
|
|
58
|
die "Unknown twilight type: \"$type\"" unless exists $H0_TWL{$type}; |
|
52
|
11
|
|
|
|
|
121
|
my $on_event = delete $arg{on_event}; |
|
53
|
11
|
|
|
|
|
21
|
my $on_noevent = delete $arg{on_noevent}; |
|
54
|
|
|
|
|
|
|
|
|
55
|
11
|
50
|
|
|
|
30
|
if (wantarray) { |
|
56
|
0
|
|
|
|
|
0
|
my %res; |
|
57
|
|
|
|
|
|
|
riseset_func(%arg)->( |
|
58
|
|
|
|
|
|
|
on_event => sub { |
|
59
|
0
|
|
|
0
|
|
0
|
my ( $evt, $jd ) = @_; |
|
60
|
0
|
|
|
|
|
0
|
$res{$evt} = $jd; |
|
61
|
0
|
|
|
|
|
0
|
$on_event->(@_); |
|
62
|
|
|
|
|
|
|
}, |
|
63
|
|
|
|
|
|
|
on_noevent => sub { |
|
64
|
0
|
|
|
0
|
|
0
|
$on_noevent->(@_); |
|
65
|
|
|
|
|
|
|
}, |
|
66
|
|
|
|
|
|
|
%arg, |
|
67
|
0
|
|
|
0
|
|
0
|
get_position => sub { _get_equatorial( $SU, $_[0] ) }, |
|
68
|
0
|
|
|
|
|
0
|
sin_h0 => sin( deg2rad( $H0_TWL{$type} ) ), |
|
69
|
|
|
|
|
|
|
); |
|
70
|
0
|
|
|
|
|
0
|
return %res; |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
riseset_func(%arg)->( |
|
74
|
|
|
|
|
|
|
%arg, |
|
75
|
247
|
|
|
247
|
|
441
|
get_position => sub { _get_equatorial( $SU, $_[0] ) }, |
|
76
|
11
|
|
|
|
|
68
|
sin_h0 => sin( deg2rad( $H0_TWL{$type} ) ), |
|
77
|
|
|
|
|
|
|
on_event => $on_event, |
|
78
|
|
|
|
|
|
|
on_noevent => $on_noevent |
|
79
|
|
|
|
|
|
|
); |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub riseset { |
|
83
|
0
|
|
|
0
|
1
|
0
|
my %arg = @_; |
|
84
|
0
|
|
|
|
|
0
|
my $pla = delete $arg{planet}; |
|
85
|
0
|
|
|
|
|
0
|
my $h0 = do { |
|
86
|
0
|
|
|
|
|
0
|
given ($pla) { |
|
87
|
0
|
|
|
|
|
0
|
$H0_SUN when $SU; |
|
88
|
0
|
|
|
|
|
0
|
$H0_MOO when $MO; |
|
89
|
0
|
|
|
|
|
0
|
default { $H0_PLA } |
|
|
0
|
|
|
|
|
0
|
|
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
}; |
|
92
|
0
|
|
|
|
|
0
|
my $func = riseset_func(%arg); |
|
93
|
|
|
|
|
|
|
sub { |
|
94
|
0
|
|
|
0
|
|
0
|
my %arg = ( on_event => sub { }, on_noevent => sub { }, @_ ); |
|
95
|
|
|
|
|
|
|
|
|
96
|
0
|
0
|
|
|
|
0
|
if (wantarray) { |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# if caller asks for a result, collect events to %res hash |
|
99
|
0
|
|
|
|
|
0
|
my %res; |
|
100
|
|
|
|
|
|
|
$func->( |
|
101
|
0
|
|
|
|
|
0
|
get_position => sub { _get_equatorial( $pla, $_[0] ) }, |
|
102
|
|
|
|
|
|
|
sin_h0 => sin( deg2rad($h0) ), |
|
103
|
|
|
|
|
|
|
on_event => sub { |
|
104
|
0
|
|
|
|
|
0
|
my ( $evt, $jd ) = @_; |
|
105
|
0
|
|
|
|
|
0
|
$arg{on_event}->(@_); |
|
106
|
0
|
|
|
|
|
0
|
$res{$evt} = { ok => 1, jd => $jd }; |
|
107
|
|
|
|
|
|
|
}, |
|
108
|
|
|
|
|
|
|
on_noevent => sub { |
|
109
|
0
|
|
|
|
|
0
|
my ($state) = shift; |
|
110
|
0
|
|
|
|
|
0
|
$arg{on_noevent}->(@_); |
|
111
|
0
|
0
|
|
|
|
0
|
my $evt = |
|
112
|
|
|
|
|
|
|
$state eq $STATE_NEVER_RISES ? $EVT_RISE : $EVT_SET; |
|
113
|
0
|
|
|
|
|
0
|
$res{$evt} = { ok => 0, state => $state }; |
|
114
|
|
|
|
|
|
|
} |
|
115
|
0
|
|
|
|
|
0
|
); |
|
116
|
0
|
|
|
|
|
0
|
return %res; |
|
117
|
|
|
|
|
|
|
} |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# if caller doesn't ask for a result, just call the function with the callbacks |
|
120
|
|
|
|
|
|
|
$func->( |
|
121
|
0
|
|
|
|
|
0
|
get_position => sub { _get_equatorial( $pla, $_[0] ) }, |
|
122
|
|
|
|
|
|
|
sin_h0 => sin( deg2rad($h0) ), |
|
123
|
|
|
|
|
|
|
on_event => $arg{on_event}, |
|
124
|
|
|
|
|
|
|
on_noevent => $arg{on_noevent}, |
|
125
|
0
|
|
|
|
|
0
|
); |
|
126
|
|
|
|
|
|
|
} |
|
127
|
0
|
|
|
|
|
0
|
} |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
sub rst { |
|
130
|
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
# build top-level function for any event and any celestial object |
|
132
|
|
|
|
|
|
|
# for given time and place |
|
133
|
1
|
|
|
1
|
1
|
1384
|
my $rst = rst_func(@_); |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub { |
|
136
|
9
|
|
|
9
|
|
3153
|
my $obj = shift; |
|
137
|
9
|
|
|
|
|
56
|
my %arg = ( on_event => sub { }, on_noevent => sub { }, @_ ); |
|
138
|
|
|
|
|
|
|
|
|
139
|
9
|
|
|
|
|
23
|
my $h0 = do { |
|
140
|
9
|
|
|
|
|
17
|
given ($obj) { |
|
141
|
9
|
|
|
|
|
27
|
$H0_SUN when $SU; |
|
142
|
8
|
|
|
|
|
49
|
$H0_MOO when $MO; |
|
143
|
8
|
|
|
|
|
34
|
default { $H0_PLA } |
|
|
8
|
|
|
|
|
17
|
|
|
144
|
|
|
|
|
|
|
} |
|
145
|
|
|
|
|
|
|
}; |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# build second level functon for calculating any event for given object |
|
148
|
|
|
|
|
|
|
my $evt_func = $rst->( |
|
149
|
18
|
|
|
|
|
228
|
get_position => sub { _get_equatorial( $obj, $_[0] ) }, |
|
150
|
9
|
|
|
|
|
72
|
sin_h0 => sin( deg2rad($h0) ) |
|
151
|
|
|
|
|
|
|
); |
|
152
|
|
|
|
|
|
|
|
|
153
|
9
|
50
|
|
|
|
27
|
if (wantarray) { |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# if caller asks for a result, collect events to %res hash |
|
156
|
0
|
|
|
|
|
0
|
my %res; |
|
157
|
0
|
|
|
|
|
0
|
for (@RS_EVENTS) { |
|
158
|
0
|
|
|
|
|
0
|
my ( $state, $jd ) = $evt_func->($_); |
|
159
|
0
|
0
|
|
|
|
0
|
if ( $state eq $_ ) { |
|
160
|
0
|
|
|
|
|
0
|
$arg{on_event}->( $_, $jd ); |
|
161
|
0
|
|
|
|
|
0
|
$res{$_} = { ok => 1, jd => $jd }; |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
else { |
|
164
|
0
|
|
|
|
|
0
|
$arg{on_noevent}->( $_, $state ); |
|
165
|
0
|
|
|
|
|
0
|
$res{$_} = { ok => 0, state => $state }; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
} |
|
168
|
0
|
|
|
|
|
0
|
return %res; |
|
169
|
|
|
|
|
|
|
} |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# if caller doesn't ask for a result, just call the function with the callbacks |
|
172
|
9
|
|
|
|
|
40
|
for (@RS_EVENTS) { |
|
173
|
27
|
|
|
|
|
7431
|
my ( $state, $jd ) = $evt_func->($_); |
|
174
|
27
|
50
|
|
|
|
48
|
if ( $state eq $_ ) { |
|
175
|
27
|
|
|
|
|
74
|
$arg{on_event}->( $_, $jd ); |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
else { |
|
178
|
0
|
|
|
|
|
|
$arg{on_noevent}->( $_, $state ); |
|
179
|
|
|
|
|
|
|
} |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
} |
|
182
|
1
|
|
|
|
|
6
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
1; |
|
185
|
|
|
|
|
|
|
__END__ |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=pod |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=encoding UTF-8 |
|
190
|
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=head1 NAME |
|
192
|
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Astro::Montenbruck::RiseSet - rise, set, transit. |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
use Astro::Montenbruck::Ephemeris::Planet qw/:ids/; |
|
198
|
|
|
|
|
|
|
use Astro::Montenbruck::MathUtils qw/frac/; |
|
199
|
|
|
|
|
|
|
use Astro::Montenbruck::RiseSet::Constants qw/:all/; |
|
200
|
|
|
|
|
|
|
use Astro::Montenbruck::RiseSet qw/:all/; |
|
201
|
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# create function for calculating rise/set/transit events for Munich, Germany, on March 23, 1989. |
|
203
|
|
|
|
|
|
|
my $func = rst( |
|
204
|
|
|
|
|
|
|
date => [1989, 3, 23], |
|
205
|
|
|
|
|
|
|
phi => 48.1, |
|
206
|
|
|
|
|
|
|
lambda => -11.6 |
|
207
|
|
|
|
|
|
|
); |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
# calculate Moon rise, set and transit |
|
210
|
|
|
|
|
|
|
$func->( |
|
211
|
|
|
|
|
|
|
$MO, |
|
212
|
|
|
|
|
|
|
on_event => sub { |
|
213
|
|
|
|
|
|
|
my ($evt, $jd) = @_; |
|
214
|
|
|
|
|
|
|
say "$evt: $jd"; |
|
215
|
|
|
|
|
|
|
}, |
|
216
|
|
|
|
|
|
|
on_noevent => sub { |
|
217
|
|
|
|
|
|
|
my ($evt, $state) = @_; # $STATE_CIRCUMPOLAR or $STATE_NEVER_RISES |
|
218
|
|
|
|
|
|
|
say "$evt: $state"; |
|
219
|
|
|
|
|
|
|
} |
|
220
|
|
|
|
|
|
|
); |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# alternatively, call the function in list context: |
|
223
|
|
|
|
|
|
|
my %res = $func->($MO); # result structure is described below |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
# calculate civil twilight |
|
226
|
|
|
|
|
|
|
twilight( |
|
227
|
|
|
|
|
|
|
date => [1989, 3, 23], |
|
228
|
|
|
|
|
|
|
phi => 48.1, |
|
229
|
|
|
|
|
|
|
lambda => -11.6, |
|
230
|
|
|
|
|
|
|
on_event => sub { |
|
231
|
|
|
|
|
|
|
my ($evt, $jd) = @_; |
|
232
|
|
|
|
|
|
|
say "$evt: $jd"; |
|
233
|
|
|
|
|
|
|
}, |
|
234
|
|
|
|
|
|
|
on_noevent => sub { |
|
235
|
|
|
|
|
|
|
my $state = shift; |
|
236
|
|
|
|
|
|
|
say $state; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
); |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
=head1 VERSION |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
Version 0.02 |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
High level interface for calculating rise, set and transit times of celestial |
|
248
|
|
|
|
|
|
|
bodies, as well as twilight of different types. |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
There are two low-level functions for calculating the events, based on based on different algorithms: |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=over |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
=item 1. |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
L<Astro::Montenbruck::RiseSet::Plarise::rst>, which calculates rise, set and transit times using I<iterative method>. |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=item 2. |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
L<Astro::Montenbruck::RiseSet::Sunset::riseset_func>, which calculates rise and set times using I<quadratic interpolation>. |
|
261
|
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=back |
|
263
|
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
Both of them are described in I<"Astronomy On The Personal Computer"> by O.Montenbruck and T.Phleger. |
|
265
|
|
|
|
|
|
|
However, they are built on different algorithms: B<riseset_func> utilizes quadratic interpolation |
|
266
|
|
|
|
|
|
|
while B<rst> is iterative. Along with rise and set, B<rst> gives transit times. At the other hand, |
|
267
|
|
|
|
|
|
|
B<riseset_func> is a base for calculating twilight. |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
To take into account I<parallax>, I<refraction> and I<apparent radius> of the |
|
270
|
|
|
|
|
|
|
bodies, we use average corrections to geometric altitudes: |
|
271
|
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=over |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=item * sunrise, sunset : B<-0 deg 50 min> |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=item * moonrise, moonset : B<0 deg 8 min> |
|
277
|
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
=item * stars and planets : B<-0 deg 34 min> |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=back |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 TWILIGHT |
|
283
|
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
The library also calculates the times of the beginning of the morning twilight |
|
285
|
|
|
|
|
|
|
(I<dawn>) and end of the evening twilight (I<dusk>). |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
Twilight occurs when Earth's upper atmosphere scatters and reflects sunlight |
|
288
|
|
|
|
|
|
|
which illuminates the lower atmosphere. Astronomers define the three stages of |
|
289
|
|
|
|
|
|
|
twilight – I<civil>, I<nautical>, and I<astronomical> – on the basis of the Sun's |
|
290
|
|
|
|
|
|
|
elevation which is the angle that the geometric center of the Sun makes with the |
|
291
|
|
|
|
|
|
|
horizon. |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=over |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item * I<astronomical> |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
Sun altitude is B<-18 deg> In the morning, the sky is completely dark before the |
|
298
|
|
|
|
|
|
|
onset of astronomical twilight, and in the evening, the sky becomes completely |
|
299
|
|
|
|
|
|
|
dark at the end of astronomical twilight. Any celestial bodies that can be |
|
300
|
|
|
|
|
|
|
viewed by the naked eye can be observed in the sky after the end of this phase. |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=item * I<nautical> |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
Sun altitude is B<-12 deg>. This twilight period is less bright than civil twilight |
|
305
|
|
|
|
|
|
|
and artificial light is generally required for outdoor activities. |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=item * I<civil> |
|
308
|
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
Sun altitude is B<-6 deg>. Civil twilight is the brightest form of twilight. |
|
310
|
|
|
|
|
|
|
There is enough natural sunlight during this period that artificial light may |
|
311
|
|
|
|
|
|
|
not be required to carry out outdoor activities. Only the brightest celestial |
|
312
|
|
|
|
|
|
|
objects can be observed by the naked eye during this time. |
|
313
|
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
=back |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=head1 CAVEATS |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Sometimes rise and set happen on different calendar dates. For example, here is the output of C<riseset.pl> |
|
319
|
|
|
|
|
|
|
script: |
|
320
|
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
$ perl .\script\riseset.pl --date=1989-03-28 --place=48.1 -11.6 --timezone=UTC |
|
322
|
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
Date : 1989-03-28 UTC |
|
324
|
|
|
|
|
|
|
Place : 48N06, 011E35 |
|
325
|
|
|
|
|
|
|
Time Zone : UTC |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
rise transit set |
|
328
|
|
|
|
|
|
|
Moon 23:34:17 03:23:59 07:10:54 |
|
329
|
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
This directly depends on time zone. Since event time is always given as Julian date, |
|
331
|
|
|
|
|
|
|
it is not hard to determine correct order of events. |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head1 EXPORT |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head2 FUNCTIONS |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=over |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=item * L</rst( %args )> |
|
340
|
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=item * L</riseset( %args )> |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=item * L</twilight( %args )> |
|
344
|
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=back |
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head2 rst( %args ) |
|
351
|
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Returns function for calculating times of rises, sets and transits of celestial bodies. See |
|
353
|
|
|
|
|
|
|
L<Astro::Montenbruck::RiseSet::Plarise/rst> . |
|
354
|
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=head3 Named Arguments |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=over |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=item * |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
B<date> - array of B<year> (astronomical, zero-based), B<month> [1..12] and B<day>, [1..31]. |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
=item * |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
B<phi> - geographical latitude, degrees, positive northward |
|
366
|
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
=item * |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
B<lambda> - geographical longitude, degrees, positive westward |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=back |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head3 Returns |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
function, which calculates rise, set and transit for a celestial body. |
|
376
|
|
|
|
|
|
|
It accepts celestial body identifier as positional argument (see L<Astro::Montenbruck::Ephemeris::Planet>) |
|
377
|
|
|
|
|
|
|
and two optional callbacks as named arguments: |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=over |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=item * |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
B<on_event($event, $jd> - callback called when the event time is determined. The first argument |
|
384
|
|
|
|
|
|
|
is one of: C<$EVT_RISE>, C<$EVT_SET> or C<$EVT_TRANSIT> constants (see L<Astro::Montenbruck::RiseSet::Constants>), |
|
385
|
|
|
|
|
|
|
the second - I<Standard Julian Date>. |
|
386
|
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=item * |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
B<on_noevent($event, $state> - callback called when the body is I<circumpolar> or I<never rises>. |
|
390
|
|
|
|
|
|
|
The first argument is then one of: C<$EVT_RISE>, C<$EVT_SET> or C<$EVT_TRANSIT>, the second - either |
|
391
|
|
|
|
|
|
|
C<$STATE_CIRCUMPOLAR> or C<$STATE_NEVER_RISES>. |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=back |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=head4 List context |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
When called in list context: |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
my %res = func(); |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
the function returns a hash: |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
( |
|
405
|
|
|
|
|
|
|
rise => $hashref, |
|
406
|
|
|
|
|
|
|
set => $hashref, |
|
407
|
|
|
|
|
|
|
transit => $hashref |
|
408
|
|
|
|
|
|
|
) |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
When rise or set takes place, C<$hashref> contains: |
|
411
|
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
{ok => 1, jd => JD} |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
JD is a Standard Julian Date. Otherwise, |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
{ok => 0, state => STATE} |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
STATE is C<$STATE_CIRCUMPOLAR> or C<$STATE_NEVER_RISES>. |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
=head2 riseset( %args ) |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
Returns function for calculating times of rises and sets of given celestial body. See |
|
424
|
|
|
|
|
|
|
L<Astro::Montenbruck::RiseSet::Sunset/riseset_func>. |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=head3 Named Arguments |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=over |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=item * |
|
431
|
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
B<planet> - celestial body identifier (see L<Astro::Montenbruck::Ephemeris::Planet>) |
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=item * |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
B<date> - array of B<year> (astronomical, zero-based), B<month> [1..12] and B<day>, [1..31]. |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=item * |
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
B<phi> - geographical latitude, degrees, positive northward |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=item * |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
B<lambda> - geographical longitude, degrees, positive westward |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=back |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=head3 Returns |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
function, which calculates rise and set times of the planet. It accepts and two callbacks as named arguments: |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
=over |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=item * |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
B<on_event($event, $jd>) |
|
457
|
|
|
|
|
|
|
callback called when the event time is determined. The first argument |
|
458
|
|
|
|
|
|
|
is one of: C<$EVT_RISE>, C<$EVT_SET> or C<$EVT_TRANSIT> constants (see L<Astro::Montenbruck::RiseSet::Constants>), |
|
459
|
|
|
|
|
|
|
the second - I<Standard Julian Date>. |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
=item * |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
B<on_noevent($state> |
|
464
|
|
|
|
|
|
|
callback called when the body is I<circumpolar> or I<never rises>. |
|
465
|
|
|
|
|
|
|
The argument is either C<$STATE_CIRCUMPOLAR> or C<$STATE_NEVER_RISES>. |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
=back |
|
468
|
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
When called in list context, returns a hash, described in L<rst( %args )/List context>, except |
|
470
|
|
|
|
|
|
|
that C<transit> key is missing. |
|
471
|
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=head2 twilight( %args ) |
|
473
|
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Function for calculating twilight. See L</TWILIGHT EVENT FUNCTION> below. |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=head3 Named Arguments |
|
477
|
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=over |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=item * |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
B<type> - type of twilight, C<$TWILIGHT_NAUTICAL>, C<$TWILIGHT_ASTRO> |
|
483
|
|
|
|
|
|
|
or C<$TWILIGHT_CIVIL>, see L<Astro::Montenbruck::RiseSet::Constants/TYPES OF TWILIGHT>. |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
=item * |
|
486
|
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
B<date> - array of B<year> (astronomical, zero-based), B<month> [1..12] and B<day>, [1..31]. |
|
488
|
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
=item * |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
B<phi> - geographical latitude, degrees, positive northward |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item * |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
B<lambda> - geographical longitude, degrees, positive westward |
|
496
|
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
=item * |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
B<on_event> - callback called when the event time is determined. The arguments are: |
|
500
|
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=over |
|
502
|
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=item * |
|
504
|
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
Event type, one of C<$EVT_RISE> or C<$EVT_SET>, L<Astro::Montenbruck::RiseSet::Constants/EVENTS>. |
|
506
|
|
|
|
|
|
|
The first indicates I<dawn>, the second - I<dusk>. |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=item * |
|
509
|
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
time of the event, I<Standard Julian date>. |
|
511
|
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=back |
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
=item * |
|
515
|
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
B<on_noevent> is called when the event never happens, either because the body never rises, |
|
517
|
|
|
|
|
|
|
or is circumpolar. The argument is respectively C<$STATE_NEVER_RISES> or C<$STATE_CIRCUMPOLAR>, |
|
518
|
|
|
|
|
|
|
see L<Astro::Montenbruck::RiseSet::Constants/STATES>. |
|
519
|
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
=back |
|
521
|
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=head1 AUTHOR |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
Sergey Krushinsky, C<< <krushi at cpan.org> >> |
|
526
|
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
|
528
|
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
Copyright (C) 2010-2022 by Sergey Krushinsky |
|
530
|
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or modify |
|
532
|
|
|
|
|
|
|
it under the same terms as Perl itself. |
|
533
|
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
=cut |