Astro-satpass

 view release on metacpan or  search on metacpan

lib/Astro/Coord/ECI/Utils.pm  view on Meta::CPAN

	    }
	}
	$rslt;
    };
}

=item $theta = mod2pi ($theta)

This subroutine reduces the given angle in radians to the range 0 <=
$theta < TWOPI.

=cut

sub mod2pi {return $_[0] - floor ($_[0] / TWOPI) * TWOPI}

=item $theta = mod360( $theta )

This subroutine reduces the given angle in degrees to the range 0 <=
$theta < 360. This is B<not> equivalent to C<$theta % 360> because the
latter loses the fractional part of $theta. It is B<not> equivalent to
C<fmod( $theta, 360 )> because the result of this subroutine is never
negative.

=cut

sub mod360 { return $_[0] - floor( $_[0] / 360 ) * 360 }

=item $radians = omega ($time);

This subroutine calculates the ecliptic longitude of the ascending node
of the Moon's mean orbit at the given B<dynamical> time.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd
Edition, Chapter 22, pages 143ff.

=cut

sub omega {
    my $T = jcent2000 (shift);	# Meeus (22.1)
    return mod2pi (deg2rad ((($T / 450000 + .0020708) * $T -
	    1934.136261) * $T + 125.04452));
}

=item $pa = position_angle( $alpha1, $delta1, $alpha2, $delta2 );

This low-level subroutine calculates the position angle in right
ascension of the second body with respect to the first, given the first
body's right ascension and declination and the second body's right
ascension and declination in that order, B<in radians>.

The return is the position angle B<in radians>, in the range
C<< -PI <= $pa < PI >>.

The algorithm comes from Jean Meeus' "Astronomical Algorithms", 2nd
Edition, page 116, but his algorithm is for the position angle of the
first body with respect to the second (i.e. the roles of the two bodies
are reversed). The order of arguments for this subroutine is consistent
with The IDL Astronomy User's Library at
L<https://github.com/wlandsman/IDLAstro>, function C<posang()>. The NASA
page for this, L<https://asd.gsfc.nasa.gov/archive/idlastro/>, is
obsolete and no longer updated, but also more descriptive.

This is exposed because in principal you could calculate the position
angle in any spherical coordinate system, you would just need to get the
order of arguments right (e.g. azimuth, elevation or longitude,
latitude).

=cut

sub position_angle {
    my ( $alpha1, $delta1, $alpha2, $delta2 ) = @_;
    my $delta_alpha = $alpha2 - $alpha1;
    return atan2( sin( $delta_alpha ),
	cos( $delta1 ) * tan( $delta2 ) -
	sin( $delta1 ) * cos( $delta_alpha ) );
}

=item $degrees = rad2deg ($radians)

This subroutine converts the given angle in radians to its equivalent
in degrees. If the argument is C<undef>, C<undef> will be returned.

=cut

sub rad2deg { return defined $_[0] ? $_[0] / PI * 180 : undef }

=item $deg_min_sec = rad2dms( $radians, $decimals, $degree_sign )

This subroutine converts the given angle in radians to its equivalent in
degrees, minutes and seconds, represented as a string. Degrees will be
suppressed if zero, and minutes will be suppressed if both degrees and
minutes are zero. If degrees are present the default delimiter is a
degree sign. The delimiters for minutes and seconds are C<'> and C<">
respectively, with the C<"> appearing before the decimal point.

The optional C<$decimals> argument specifies the number of decimal
places in the seconds value, and defaults to C<3>.

The optional C<$degree_sign> argument specifies the degree sign. The
default is a Unicode degree sign, C<"\N{DEGREE SIGN}">, a.k.a.
C<"\N{U+00B0}">.

=cut

sub rad2dms {
    my ( $rad, $dp, $ds ) = @_;
    defined $rad
	or return $rad;
    defined $dp
	or $dp = 3;
    defined $ds
	or $ds = "\N{U+00B0}";
    my $wid = $dp + 3;

    ( $rad, my $sgn ) = $rad < 0 ? ( -$rad, '-' ) : ( $rad, '' );
    my $sec = rad2deg( $rad );
    ( $sec, my $deg ) = modf( $sec );
    ( $sec, my $min ) = modf( $sec * 60 );
    $sec *= 60;
    my $rslt;
    if ( $deg ) {



( run in 0.771 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )