File Coverage

lib/Astro/Montenbruck/Ephemeris/Planet.pm
Criterion Covered Total %
statement 56 57 98.2
branch n/a
condition n/a
subroutine 10 11 90.9
pod 3 3 100.0
total 69 71 97.1


line stmt bran cond sub pod time code
1             package Astro::Montenbruck::Ephemeris::Planet;
2 6     6   1643 use strict;
  6         12  
  6         160  
3 6     6   29 use warnings;
  6         13  
  6         143  
4              
5 6     6   1769 use Readonly;
  6         13707  
  6         296  
6 6     6   47 use Math::Trig qw/:pi rad2deg deg2rad/;
  6         13  
  6         734  
7 6     6   425 use Astro::Montenbruck::MathUtils qw/frac polar cart /;
  6         9  
  6         1390  
8              
9             our $VERSION = 0.04;
10              
11             Readonly our $MO => 'Moon';
12             Readonly our $SU => 'Sun';
13             Readonly our $ME => 'Mercury';
14             Readonly our $VE => 'Venus';
15             Readonly our $MA => 'Mars';
16             Readonly our $JU => 'Jupiter';
17             Readonly our $SA => 'Saturn';
18             Readonly our $UR => 'Uranus';
19             Readonly our $NE => 'Neptune';
20             Readonly our $PL => 'Pluto';
21              
22             Readonly::Array our @PLANETS =>
23             ( $MO, $SU, $ME, $VE, $MA, $JU, $SA, $UR, $NE, $PL );
24              
25 6     6   38 use Exporter qw/import/;
  6         13  
  6         3287  
26              
27             our %EXPORT_TAGS = (
28             ids => [ qw/$MO $SU $ME $VE $MA $JU $SA $UR $NE $PL/ ],
29             funcs => [ qw/true2apparent light_travel/ ]
30             );
31             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'ids'} }, '@PLANETS', @{ $EXPORT_TAGS{'funcs'} });
32              
33             sub new {
34 942     942 1 2937 my ( $class, %arg ) = @_;
35 942         8183 bless { _id => $arg{id}, }, $class;
36             }
37              
38              
39             # from the time derivatives of the polar coordinates (l, b, r)
40             # derive the components of the velocity vector in ecliptic coordinates
41             sub _posvel {
42 1002     1002   1829 my ( $self, $l, $b, $r, $dl, $db, $dr ) = @_;
43 1002         1409 my $cl = cos($l);
44 1002         1273 my $sl = sin($l);
45 1002         1243 my $cb = cos($b);
46 1002         1243 my $sb = sin($b);
47 1002         1823 my $x = $r * $cl * $cb;
48 1002         1906 my $vx = $dr * $cl * $cb - $dl * $r * $sl * $cb - $db * $r * $cl * $sb;
49 1002         1307 my $y = $r * $sl * $cb;
50 1002         1636 my $vy = $dr * $sl * $cb + $dl * $r * $cl * $cb - $db * $r * $sl * $sb;
51 1002         1286 my $z = $r * $sb;
52 1002         1377 my $vz = $dr * $sb + $db * $r * $cb;
53              
54 1002         2436 $x, $y, $z, $vx, $vy, $vz;
55             }
56              
57             # geocentric ecliptic coordinates (light-time corrected)
58             sub _geocentric {
59 501     501   6073 my ( $self, $t, $hpla_ref, $gsun_ref ) = @_;
60              
61 501         1207 my $m = pi2 * frac( 0.9931266 + 99.9973604 * $t ); # Sun
62             # calculate the heliocentric velosity vector, which is required
63             # to take account of the various aberration effects.
64 501         1155 my $dls = 172.00 + 5.75 * sin($m);
65 501         875 my $drs = 2.87 * cos($m);
66 501         761 my $dbs = 0.0;
67             ###
68 501         1191 my ( $dl, $db, $dr ) = $self->_lbr_geo($t);
69              
70             # ecliptic geocentric coordinates of the Sun
71             my ( $xs, $ys, $zs, $vxs, $vys, $vzs ) =
72 501         1480 $self->_posvel( $gsun_ref->{l}, $gsun_ref->{b}, $gsun_ref->{r}, $dls, $dbs, $drs );
73             # ecliptic heliocentric coordinates of the planet
74             my ( $xp, $yp, $zp, $vx, $vy, $vz ) =
75 501         1174 $self->_posvel( $hpla_ref->{l}, $hpla_ref->{b}, $hpla_ref->{r}, $dl, $db, $dr );
76 501         841 my $x = $xp + $xs;
77 501         696 my $y = $yp + $ys;
78 501         708 my $z = $zp + $zs;
79              
80             # mean heliocentric motion
81 501         824 my $delta0 = sqrt( $x * $x + $y * $y + $z * $z );
82 501         707 my $fac = 0.00578 * $delta0 * 1E-4;
83              
84             # correct for light travel
85 501         739 $x -= $fac * ( $vx + $vxs );
86 501         702 $y -= $fac * ( $vy + $vys );
87 501         743 $z -= $fac * ( $vz + $vzs );
88              
89 501         1286 $x, $y, $z # ecliptic geocentric coordinates of the planet
90             }
91              
92             sub apparent {
93 36     36 1 65 my $self = shift;
94 36         67 my ( $t, $lbr, $sun, $nut_func ) = @_;
95 36         58 my ( $l, $b, $r ) = @$lbr; # $self->heliocentric($t);
96             # geocentric ecliptic coordinates (light-time corrected, referred to the mean equinox of date)
97 36         162 my @mean = $self->_geocentric( $t, { l => $l, b => $b, r => $r }, $sun );
98             # true equinox of date
99 36         125 my @date = $nut_func->(\@mean);
100             # rectangular -> polar
101 36         120 ($r, $b, $l) = polar(@date);
102 36         94 rad2deg($l), rad2deg($b), $r;
103             }
104              
105              
106             sub heliocentric {
107 0     0 1   die "Must be overriden by a descendant";
108             }
109              
110              
111              
112              
113             1;
114             __END__
115              
116             =pod
117              
118             =encoding UTF-8
119              
120             =head1 NAME
121              
122             Astro::Montenbruck::Ephemeris::Planet - Base class for a planet.
123              
124             =head1 SYNOPSIS
125              
126             package Astro::Montenbruck::Ephemeris::Planet::Mercury;
127             use base qw/Astro::Montenbruck::Ephemeris::Planet/;
128             ...
129              
130             sub heliocentric {
131             # implement the method
132             }
133              
134              
135             =head1 DESCRIPTION
136              
137             Base class for a planet. Designed to be extended. Used internally in
138             Astro::Montenbruck::Ephemeris modules. Subclasses must implement B<heliocentric>
139             method.
140              
141             =head1 SUBROUTINES/METHODS
142              
143             =head2 $planet = Astro::Montenbruck::Ephemeris::Planet->new( $id )
144              
145             Constructor. B<$id> is identifier from C<@PLANETS> array (See L</"EXPORTED CONSTANTS">).
146              
147             =head2 $self->apparent($t, $lbr, $sun, $nut_func)
148              
149             Geocentric ecliptic coordinates of a planet, referred to the true equinox of date.
150              
151             =head3 Arguments
152              
153             =over
154              
155             =item *
156              
157             B<$t> — time in Julian centuries since J2000: C<(JD-2451545.0) / 36525.0>
158              
159             =item *
160              
161             B<$lbr> — arrayref of heliocentric coordinates of the planet
162             returned by L<$self-&gt;heliocentric($t)>
163              
164             =item *
165              
166             B<$sun> — ecliptic geocentric coordinates of the Sun (hashref with B<'l'>, B<'b'>, B<'r'> keys),
167             returned by L<Astro::Montenbruck::Ephemeris::Planet::Sun::sunpos($t)>
168              
169              
170             =item *
171              
172             B<$nut_func> — function for converting geocntric coordinates from mean to true equinox of date,
173             returned by L<Astro::Montenbruck::NutEqu::mean2true($t)>
174              
175              
176             =back
177              
178             =head3 Returns
179              
180             Array of geocentric ecliptical coordinates.
181              
182             =over
183              
184             =item * longitude, arc-degrees
185              
186             =item * latitude, arc-degrees
187              
188             =item * distance from Earth, AU
189              
190             =back
191              
192             =head2 $self->heliocentric($t)
193              
194             Given time in centuries since epoch 2000.0, calculate heliocentric ecliptical
195             coordinates C<($l, $b, $r)>.
196              
197             =over
198              
199             =item * B<$l> — longitude, arc-degrees
200              
201             =item * B<$b> — latitude, arc-degrees
202              
203             =item * B<$r> — distance from Earth, A.U.
204              
205             =back
206              
207              
208              
209             =head1 EXPORTED CONSTANTS
210              
211             =over
212              
213             =item * C<$MO> — Moon
214              
215             =item * C<$SU> — Sun
216              
217             =item * C<$ME> — Mercury
218              
219             =item * C<$VE> — Venus
220              
221             =item * C<$MA> — Mars
222              
223             =item * C<$JU> — Jupiter
224              
225             =item * C<$SA> — Saturn
226              
227             =item * C<$UR> — Uranus
228              
229             =item * C<$NE> — Neptune
230              
231             =item * C<$PL> — Pluto
232              
233             =item * C<@PLANETS> — array containing all the ids listed above
234              
235             =back
236              
237              
238             =head1 AUTHOR
239              
240             Sergey Krushinsky, C<< <krushi at cpan.org> >>
241              
242             =head1 COPYRIGHT AND LICENSE
243              
244             Copyright (C) 2009-2022 by Sergey Krushinsky
245              
246             This library is free software; you can redistribute it and/or modify
247             it under the same terms as Perl itself.
248              
249             =cut