File Coverage

lib/Astro/Montenbruck/Ephemeris/Planet/Moon.pm
Criterion Covered Total %
statement 224 224 100.0
branch 2 2 100.0
condition n/a
subroutine 19 19 100.0
pod 2 2 100.0
total 247 247 100.0


line stmt bran cond sub pod time code
1             package Astro::Montenbruck::Ephemeris::Planet::Moon;
2              
3 2     2   1299 use strict;
  2         5  
  2         61  
4 2     2   16 use warnings;
  2         4  
  2         62  
5              
6 2     2   11 use Math::Trig qw/:pi rad2deg/;
  2         26  
  2         331  
7 2     2   16 use Astro::Montenbruck::Ephemeris::Planet;
  2         26  
  2         112  
8 2     2   12 use base qw/Astro::Montenbruck::Ephemeris::Planet/;
  2         14  
  2         183  
9 2     2   27 use Astro::Montenbruck::Ephemeris::Planet qw/$MO/;
  2         5  
  2         203  
10 2     2   16 use Astro::Montenbruck::MathUtils qw /frac sine ARCS reduce_deg/;
  2         4  
  2         147  
11 2     2   907 use Astro::Montenbruck::Ephemeris::Pert qw /addthe/;
  2         5  
  2         4940  
12              
13             our $VERSION = 0.01;
14              
15             sub new {
16 190     190 1 388 my $class = shift;
17 190         744 $class->SUPER::new( id => $MO );
18             }
19              
20             # calculate long-periodic changes of the mean elements
21             # l,l',F,D and L0 as well as dgamma
22             sub _long_periodic {
23 190     190   312 my $t = shift;
24              
25 190         703 my $s1 = sine( 0.19833 + 0.05611 * $t );
26 190         517 my $s2 = sine( 0.27869 + 0.04508 * $t );
27 190         515 my $s3 = sine( 0.16827 - 0.36903 * $t );
28 190         430 my $s4 = sine( 0.34734 - 5.37261 * $t );
29 190         471 my $s5 = sine( 0.10498 - 5.37899 * $t );
30 190         482 my $s6 = sine( 0.42681 - 0.41855 * $t );
31 190         413 my $s7 = sine( 0.14943 - 5.37511 * $t );
32 190         465 my $dl0 =
33             0.84 * $s1 +
34             0.31 * $s2 +
35             14.27 * $s3 +
36             7.26 * $s4 +
37             0.28 * $s5 +
38             0.24 * $s6;
39 190         441 my $dl =
40             2.94 * $s1 +
41             0.31 * $s2 +
42             14.27 * $s3 +
43             9.34 * $s4 +
44             1.12 * $s5 +
45             0.83 * $s6;
46 190         357 my $dls = -6.40 * $s1 - 1.89 * $s6;
47 190         435 my $df =
48             0.21 * $s1 +
49             0.31 * $s2 +
50             14.27 * $s3 -
51             88.70 * $s4 -
52             15.30 * $s5 +
53             0.24 * $s6 -
54             1.86 * $s7;
55 190         350 my $dd = $dl0 - $dls;
56 190         532 my $dgam =
57             -3332e-9 * sine( 0.59734 - 5.37261 * $t ) -
58             539e-9 * sine( 0.35498 - 5.37899 * $t ) -
59             64e-9 * sine( 0.39943 - 5.37511 * $t );
60              
61 190         695 $dl0, $dl, $dls, $df, $dd, $dgam;
62             }
63              
64             sub position {
65 190     190 1 473 my ( $self, $t ) = @_;
66 190         559 my ( %co, %si );
67 190         0 my ( $dlam, $ds, $gam1c, $n );
68 190         291 my $sinpi = 3422.7;
69 190         357 my ( $dl0, $dl, $dls, $df, $dd, $dgam, $l, $l0, $ls, $f, $d );
70              
71             # INIT: calculates the mean elements and their sine and cosine
72             # l mean anomaly of the Moon
73             # l' mean anomaly of the Sun
74             # F mean distance from the node
75             # D mean elongation from the Sun
76             my $init = sub {
77 190     190   378 my $t2 = $t * $t;
78              
79 190         454 ( $dl0, $dl, $dls, $df, $dd, $dgam ) = _long_periodic($t);
80              
81 190         530 $l0 = pi2 * frac( 0.60643382 + 1336.85522467 * $t - 0.00000313 * $t2 ) +
82             $dl0 / ARCS;
83 190         515 $l = pi2 * frac( 0.37489701 + 1325.55240982 * $t + 0.00002565 * $t2 ) +
84             $dl / ARCS;
85 190         430 $ls = pi2 * frac( 0.99312619 + 99.99735956 * $t - 0.00000044 * $t2 ) +
86             $dls / ARCS;
87 190         445 $f = pi2 * frac( 0.25909118 + 1342.22782980 * $t - 0.00000892 * $t2 ) +
88             $df / ARCS;
89 190         450 $d = pi2 * frac( 0.82736186 + 1236.85308708 * $t - 0.00000397 * $t2 ) +
90             $dd / ARCS;
91              
92 190         539 for my $i ( 1 .. 4 ) {
93              
94             my ( $arg, $max, $fac ) = (
95 190         530 sub { $l, 4, 1.000002208 },
96 190         545 sub { $ls, 3, 0.997504612 - 0.002495388 * $t },
97 190         501 sub { $f, 4, 1.000002708 + 139.978 * $dgam },
98 190         482 sub { $d, 6, 1.0 }
99 760         4147 )[ $i - 1 ]->();
100              
101 760         3461 $co{0}->{$i} = 1.0;
102 760         1807 $co{1}->{$i} = cos($arg) * $fac;
103 760         1262 $si{0}->{$i} = 0.0;
104 760         1508 $si{1}->{$i} = sin($arg) * $fac;
105              
106 760         1482 for ( 2 .. $max ) {
107 2470         4244 my $k = $_ - 1;
108             ( $co{$_}->{$i}, $si{$_}->{$i} ) = addthe(
109             $co{$k}->{$i}, $si{$k}->{$i},
110 2470         6279 $co{1}->{$i}, $si{1}->{$i}
111             );
112             }
113 760         1462 for ( 1 .. $max ) {
114 3230         7029 $co{ -$_ }->{$i} = $co{$_}->{$i};
115 3230         7079 $si{ -$_ }->{$i} = -$si{$_}->{$i};
116             }
117             }
118 190         1509 };
119              
120             # TERM calculates X = cos(p * arg1 + q * arg2 + r * arg3 + s * arg4)
121             # and Y = sin(p * arg1 + q * arg2 + r * arg3 + s * arg4)
122             my $term = sub {
123 21470     21470   35614 my @pqrs = @_;
124 21470         34785 my %i = map { $_ + 1, $pqrs[$_] } ( 0 .. 3 );
  85880         164763  
125 21470         40485 my $x = 1.0;
126 21470         29708 my $y = 0.0;
127              
128 21470         36003 for ( 1 .. 4 ) {
129 85880 100       172605 if ( $i{$_} != 0 ) {
130 49970         73616 my $j = $i{$_};
131 49970         116800 ( $x, $y ) = addthe( $x, $y, $co{$j}->{$_}, $si{$j}->{$_} );
132             }
133             }
134 21470         50912 $x, $y;
135 190         705 };
136              
137             my $addsol = sub {
138 19760     19760   36364 my ( $coeffl, $coeffs, $coeffg, $coeffp, $p, $q, $r, $s ) = @_;
139 19760         33292 my ( $x, $y ) = $term->( $p, $q, $r, $s );
140              
141 19760         31979 $dlam += $coeffl * $y;
142 19760         27552 $ds += $coeffs * $y;
143 19760         26914 $gam1c += $coeffg * $x;
144 19760         30142 $sinpi += $coeffp * $x;
145 190         649 };
146              
147             my $solar_1 = sub {
148 190     190   550 $addsol->( 13.902, 14.06, -0.001, 0.2607, 0, 0, 0, 4 );
149 190         518 $addsol->( 0.403, -4.01, +0.394, 0.0023, 0, 0, 0, 3 );
150 190         502 $addsol->( 2369.912, 2373.36, +0.601, 28.2333, 0, 0, 0, 2 );
151 190         479 $addsol->( -125.154, -112.79, -0.725, -0.9781, 0, 0, 0, 1 );
152 190         523 $addsol->( 1.979, 6.98, -0.445, 0.0433, 1, 0, 0, 4 );
153 190         472 $addsol->( 191.953, 192.72, +0.029, 3.0861, 1, 0, 0, 2 );
154 190         483 $addsol->( -8.466, -13.51, +0.455, -0.1093, 1, 0, 0, 1 );
155 190         481 $addsol->( 22639.500, 22609.07, +0.079, 186.5398, 1, 0, 0, 0 );
156 190         507 $addsol->( 18.609, 3.59, -0.094, 0.0118, 1, 0, 0, -1 );
157 190         508 $addsol->( -4586.465, -4578.13, -0.077, 34.3117, 1, 0, 0, -2 );
158 190         559 $addsol->( +3.215, 5.44, +0.192, -0.0386, 1, 0, 0, -3 );
159 190         501 $addsol->( -38.428, -38.64, +0.001, 0.6008, 1, 0, 0, -4 );
160 190         495 $addsol->( -0.393, -1.43, -0.092, 0.0086, 1, 0, 0, -6 );
161 190         497 $addsol->( -0.289, -1.59, +0.123, -0.0053, 0, 1, 0, 4 );
162 190         562 $addsol->( -24.420, -25.10, +0.040, -0.3000, 0, 1, 0, 2 );
163 190         552 $addsol->( 18.023, 17.93, +0.007, 0.1494, 0, 1, 0, 1 );
164 190         521 $addsol->( -668.146, -126.98, -1.302, -0.3997, 0, 1, 0, 0 );
165 190         527 $addsol->( 0.560, 0.32, -0.001, -0.0037, 0, 1, 0, -1 );
166 190         496 $addsol->( -165.145, -165.06, +0.054, 1.9178, 0, 1, 0, -2 );
167 190         489 $addsol->( -1.877, -6.46, -0.416, 0.0339, 0, 1, 0, -4 );
168 190         532 $addsol->( 0.213, 1.02, -0.074, 0.0054, 2, 0, 0, 4 );
169 190         530 $addsol->( 14.387, 14.78, -0.017, 0.2833, 2, 0, 0, 2 );
170 190         492 $addsol->( -0.586, -1.20, +0.054, -0.0100, 2, 0, 0, 1 );
171 190         481 $addsol->( 769.016, 767.96, +0.107, 10.1657, 2, 0, 0, 0 );
172 190         507 $addsol->( +1.750, 2.01, -0.018, 0.0155, 2, 0, 0, -1 );
173 190         549 $addsol->( -211.656, -152.53, +5.679, -0.3039, 2, 0, 0, -2 );
174 190         509 $addsol->( +1.225, 0.91, -0.030, -0.0088, 2, 0, 0, -3 );
175 190         504 $addsol->( -30.773, -34.07, -0.308, 0.3722, 2, 0, 0, -4 );
176 190         496 $addsol->( -0.570, -1.40, -0.074, 0.0109, 2, 0, 0, -6 );
177 190         482 $addsol->( -2.921, -11.75, +0.787, -0.0484, 1, 1, 0, 2 );
178 190         558 $addsol->( +1.267, 1.52, -0.022, 0.0164, 1, 1, 0, 1 );
179 190         533 $addsol->( -109.673, -115.18, +0.461, -0.9490, 1, 1, 0, 0 );
180 190         524 $addsol->( -205.962, -182.36, +2.056, +1.4437, 1, 1, 0, -2 );
181 190         507 $addsol->( 0.233, 0.36, 0.012, -0.0025, 1, 1, 0, -3 );
182 190         430 $addsol->( -4.391, -9.66, -0.471, 0.0673, 1, 1, 0, -4 );
183 190         975 };
184              
185             my $solar_2 = sub {
186 190     190   519 $addsol->( 0.283, 1.53, -0.111, +0.0060, 1, -1, 0, +4 );
187 190         505 $addsol->( 14.577, 31.70, -1.540, +0.2302, 1, -1, 0, 2 );
188 190         535 $addsol->( 147.687, 138.76, +0.679, +1.1528, 1, -1, 0, 0 );
189 190         568 $addsol->( -1.089, 0.55, +0.021, 0.0, 1, -1, 0, -1 );
190 190         540 $addsol->( 28.475, 23.59, -0.443, -0.2257, 1, -1, 0, -2 );
191 190         517 $addsol->( -0.276, -0.38, -0.006, -0.0036, 1, -1, 0, -3 );
192 190         543 $addsol->( 0.636, 2.27, +0.146, -0.0102, 1, -1, 0, -4 );
193 190         535 $addsol->( -0.189, -1.68, +0.131, -0.0028, 0, 2, 0, 2 );
194 190         495 $addsol->( -7.486, -0.66, -0.037, -0.0086, 0, 2, 0, 0 );
195 190         490 $addsol->( -8.096, -16.35, -0.740, 0.0918, 0, 2, 0, -2 );
196 190         594 $addsol->( -5.741, -0.04, 0.0, -0.0009, 0, 0, 2, 2 );
197 190         491 $addsol->( 0.255, 0.0, 0.0, 0.0, 0, 0, 2, 1 );
198 190         508 $addsol->( -411.608, -0.20, 0.0, -0.0124, 0, 0, 2, 0 );
199 190         507 $addsol->( 0.584, 0.84, 0.0, +0.0071, 0, 0, 2, -1 );
200 190         531 $addsol->( -55.173, -52.14, 0.0, -0.1052, 0, 0, 2, -2 );
201 190         501 $addsol->( 0.254, 0.25, 0.0, -0.0017, 0, 0, 2, -3 );
202 190         579 $addsol->( +0.025, -1.67, 0.0, +0.0031, 0, 0, 2, -4 );
203 190         517 $addsol->( 1.060, 2.96, -0.166, 0.0243, 3, 0, 0, +2 );
204 190         500 $addsol->( 36.124, 50.64, -1.300, 0.6215, 3, 0, 0, 0 );
205 190         545 $addsol->( -13.193, -16.40, +0.258, -0.1187, 3, 0, 0, -2 );
206 190         540 $addsol->( -1.187, -0.74, +0.042, 0.0074, 3, 0, 0, -4 );
207 190         586 $addsol->( -0.293, -0.31, -0.002, 0.0046, 3, 0, 0, -6 );
208 190         552 $addsol->( -0.290, -1.45, +0.116, -0.0051, 2, 1, 0, 2 );
209 190         574 $addsol->( -7.649, -10.56, +0.259, -0.1038, 2, 1, 0, 0 );
210 190         528 $addsol->( -8.627, -7.59, +0.078, -0.0192, 2, 1, 0, -2 );
211 190         527 $addsol->( -2.740, -2.54, +0.022, 0.0324, 2, 1, 0, -4 );
212 190         879 $addsol->( 1.181, 3.32, -0.212, 0.0213, 2, -1, 0, +2 );
213 190         527 $addsol->( 9.703, 11.67, -0.151, 0.1268, 2, -1, 0, 0 );
214 190         596 $addsol->( -0.352, -0.37, +0.001, -0.0028, 2, -1, 0, -1 );
215 190         628 $addsol->( -2.494, -1.17, -0.003, -0.0017, 2, -1, 0, -2 );
216 190         561 $addsol->( 0.360, 0.20, -0.012, -0.0043, 2, -1, 0, -4 );
217 190         509 $addsol->( -1.167, -1.25, +0.008, -0.0106, 1, 2, 0, 0 );
218 190         541 $addsol->( -7.412, -6.12, +0.117, 0.0484, 1, 2, 0, -2 );
219 190         508 $addsol->( -0.311, -0.65, -0.032, 0.0044, 1, 2, 0, -4 );
220 190         557 $addsol->( +0.757, 1.82, -0.105, 0.0112, 1, -2, 0, 2 );
221 190         531 $addsol->( +2.580, 2.32, +0.027, 0.0196, 1, -2, 0, 0 );
222 190         520 $addsol->( +2.533, 2.40, -0.014, -0.0212, 1, -2, 0, -2 );
223 190         535 $addsol->( -0.344, -0.57, -0.025, +0.0036, 0, 3, 0, -2 );
224 190         519 $addsol->( -0.992, -0.02, 0.0, 0.0, 1, 0, 2, 2 );
225 190         508 $addsol->( -45.099, -0.02, 0.0, -0.0010, 1, 0, 2, 0 );
226 190         545 $addsol->( -0.179, -9.52, 0.0, -0.0833, 1, 0, 2, -2 );
227 190         508 $addsol->( -0.301, -0.33, 0.0, 0.0014, 1, 0, 2, -4 );
228 190         526 $addsol->( -6.382, -3.37, 0.0, -0.0481, 1, 0, -2, 2 );
229 190         504 $addsol->( 39.528, 85.13, 0.0, -0.7136, 1, 0, -2, 0 );
230 190         545 $addsol->( 9.366, 0.71, 0.0, -0.0112, 1, 0, -2, -2 );
231 190         458 $addsol->( 0.202, 0.02, 0.0, 0.0, 1, 0, -2, -4 );
232 190         1496 };
233              
234             my $solar_3 = sub {
235 190     190   528 $addsol->( 0.415, 0.10, 0.0, 0.0013, 0, 1, 2, 0 );
236 190         544 $addsol->( -2.152, -2.26, 0.0, -0.0066, 0, 1, 2, -2 );
237 190         573 $addsol->( -1.440, -1.30, 0.0, +0.0014, 0, 1, -2, 2 );
238 190         569 $addsol->( 0.384, -0.04, 0.0, 0.0, 0, 1, -2, -2 );
239 190         499 $addsol->( +1.938, +3.60, -0.145, +0.0401, 4, 0, 0, 0 );
240 190         544 $addsol->( -0.952, -1.58, +0.052, -0.0130, 4, 0, 0, -2 );
241 190         515 $addsol->( -0.551, -0.94, +0.032, -0.0097, 3, 1, 0, 0 );
242 190         511 $addsol->( -0.482, -0.57, +0.005, -0.0045, 3, 1, 0, -2 );
243 190         505 $addsol->( 0.681, 0.96, -0.026, 0.0115, 3, -1, 0, 0 );
244 190         559 $addsol->( -0.297, -0.27, 0.002, -0.0009, 2, 2, 0, -2 );
245 190         477 $addsol->( 0.254, +0.21, -0.003, 0.0, 2, -2, 0, -2 );
246 190         502 $addsol->( -0.250, -0.22, 0.004, 0.0014, 1, 3, 0, -2 );
247 190         531 $addsol->( -3.996, 0.0, 0.0, +0.0004, 2, 0, 2, 0 );
248 190         493 $addsol->( 0.557, -0.75, 0.0, -0.0090, 2, 0, 2, -2 );
249 190         520 $addsol->( -0.459, -0.38, 0.0, -0.0053, 2, 0, -2, 2 );
250 190         549 $addsol->( -1.298, 0.74, 0.0, +0.0004, 2, 0, -2, 0 );
251 190         544 $addsol->( 0.538, 1.14, 0.0, -0.0141, 2, 0, -2, -2 );
252 190         527 $addsol->( 0.263, 0.02, 0.0, 0.0, 1, 1, 2, 0 );
253 190         492 $addsol->( 0.426, +0.07, 0.0, -0.0006, 1, 1, -2, -2 );
254 190         499 $addsol->( -0.304, +0.03, 0.0, +0.0003, 1, -1, 2, 0 );
255 190         570 $addsol->( -0.372, -0.19, 0.0, -0.0027, 1, -1, -2, 2 );
256 190         504 $addsol->( +0.418, 0.0, 0.0, 0.0, 0, 0, 4, 0 );
257 190         450 $addsol->( -0.330, -0.04, 0.0, 0.0, 3, 0, 2, 0 );
258 190         830 };
259              
260             # part N of the perturbations of ecliptic latitude
261             my $solar_n = sub {
262             my $addn = sub {
263 1710         2621 my $coeffn = shift;
264 1710         2917 my ( $x, $y ) = $term->(@_);
265 1710         3538 $n += $coeffn * $y;
266 190     190   1171 };
267              
268 190         669 $addn->( -526.069, 0, 0, 1, -2 );
269 190         523 $addn->( -3.352, 0, 0, 1, -4 );
270 190         500 $addn->( +44.297, +1, 0, 1, -2 );
271 190         485 $addn->( -6.000, +1, 0, 1, -4 );
272 190         489 $addn->( +20.599, -1, 0, 1, 0 );
273 190         556 $addn->( -30.598, -1, 0, 1, -2 );
274 190         482 $addn->( -24.649, -2, 0, 1, 0 );
275 190         478 $addn->( -2.000, -2, 0, 1, -2 );
276 190         421 $addn->( -22.571, 0, +1, 1, -2 );
277 190         676 };
278              
279             # perturbations of ecliptic latitude by Venus and Moon
280             my $planetary = sub {
281 190     190   765 $dlam +=
282             +0.82 * sine( 0.7736 - 62.5512 * $t ) +
283             0.31 * sine( 0.0466 - 125.1025 * $t ) +
284             0.35 * sine( 0.5785 - 25.1042 * $t ) +
285             0.66 * sine( 0.4591 + 1335.8075 * $t ) +
286             0.64 * sine( 0.3130 - 91.5680 * $t ) +
287             1.14 * sine( 0.1480 + 1331.2898 * $t ) +
288             0.21 * sine( 0.5918 + 1056.5859 * $t ) +
289             0.44 * sine( 0.5784 + 1322.8595 * $t ) +
290             0.24 * sine( 0.2275 - 5.7374 * $t ) +
291             0.28 * sine( 0.2965 + 2.6929 * $t ) +
292             0.33 * sine( 0.3132 + 6.3368 * $t );
293 190         652 };
294              
295             #
296             # start
297             #
298 190         599 $init->();
299 190         530 $solar_1->();
300 190         507 $solar_2->();
301 190         503 $solar_3->();
302 190         464 $solar_n->();
303 190         512 $planetary->();
304              
305 190         864 my $lambda = reduce_deg( rad2deg( $l0 + $dlam / ARCS ) );
306 190         364 my $s = $f + $ds / ARCS;
307 190         378 my $fac = 1.000002708 + 139.978 * $dgam;
308 190         494 my $beta =
309             ( $fac * ( 18518.511 + 1.189 + $gam1c ) * sin($s) -
310             6.24 * sin( 3 * $s ) +
311             $n ) / 3600.0;
312              
313             # equatorial horizontal parallax
314 190         317 $sinpi *= 0.999953253;
315              
316             # the original: wrong value my $r = ARCS / $sinpi;
317 190         336 my $delta = 8.794 / $sinpi;
318              
319 190         11046 $lambda, $beta, $delta
320              
321             }
322              
323             1;
324              
325             __END__
326              
327             =pod
328              
329             =encoding UTF-8
330              
331             =head1 NAME
332              
333             Astro::Montenbruck::Ephemeris::Planet::Moon - Moon.
334              
335             =head1 SYNOPSIS
336              
337             use Astro::Montenbruck::Ephemeris::Planet::Moon;
338             my $planet = Astro::Montenbruck::Ephemeris::Planet::Moon->new();
339             my @geo = $planet->position($t); # apparent geocentric ecliptical coordinates
340              
341             =head1 DESCRIPTION
342              
343             Child class of L<Astro::Montenbruck::Ephemeris::Planet>, responsible for calculating
344             B<Moon> position.
345              
346             =head1 METHODS
347              
348             =head2 Astro::Montenbruck::Ephemeris::Planet::Moon->new
349              
350             Constructor.
351              
352             =head2 $self->position($t)
353              
354             Geocentric ecliptic coordinates of the Moon
355              
356             =head3 Arguments
357              
358             =over
359              
360             =item B<$t> — time in Julian centuries since J2000: (JD-2451545.0)/36525.0
361              
362             =back
363              
364             =head3 Returns
365              
366             Hash of geocentric ecliptical coordinates.
367              
368             =over
369              
370             =item * B<x> — geocentric longitude, arc-degrees
371              
372             =item * B<y> — geocentric latitude, arc-degrees
373              
374             =item * B<z> — distance from Earth, AU
375              
376             =back
377              
378              
379             =head1 AUTHOR
380              
381             Sergey Krushinsky, C<< <krushi at cpan.org> >>
382              
383             =head1 COPYRIGHT AND LICENSE
384              
385             Copyright (C) 2009-2019 by Sergey Krushinsky
386              
387             This library is free software; you can redistribute it and/or modify
388             it under the same terms as Perl itself.
389              
390             =cut