Astro-Sunrise
view release on metacpan or search on metacpan
lib/Astro/Sunrise.pm view on Meta::CPAN
my $t;
if ( $cost >= 1.0 ) {
if ($polar eq 'retval') {
return ('night', 'night');
}
carp "Sun never rises!!\n";
$t = 0.0; # Sun always below altit
}
elsif ( $cost <= -1.0 ) {
if ($polar eq 'retval') {
return ('day', 'day');
}
carp "Sun never sets!!\n";
$t = 12.0; # Sun always above altit
}
else {
my $arc = acosd($cost); # The diurnal arc
$t = $arc / $ang_spd; # Time to traverse the diurnal arc, hours
if ($trace) {
printf $trace "Diurnal arc $arc -> $t hours (%s)\n", _fmt_dur($t);
}
}
# Store rise and set times - in hours UT
my $hour_rise_ut = $tsouth - $t;
my $hour_set_ut = $tsouth + $t;
if ($trace) {
printf $trace "For day $d (%s), sunrise at $hour_rise_ut (%s)\n", _fmt_hr(24 * ($d - int($d)), $lon),
_fmt_hr($hour_rise_ut, $lon);
printf $trace "For day $d (%s), sunset at $hour_set_ut (%s)\n", _fmt_hr(24 * ($d - int($d)), $lon),
_fmt_hr($hour_set_ut , $lon);
}
return($hour_rise_ut, $hour_set_ut);
}
#########################################################################################################
#
#
# FUNCTIONAL SEQUENCE for GMST0
#
# _GIVEN
# Day number
#
# _THEN
#
# computes GMST0, the Greenwich Mean Sidereal Time
# at 0h UT (i.e. the sidereal time at the Greenwich meridian at
# 0h UT). GMST is then the sidereal time at Greenwich at any
# time of the day..
#
#
# _RETURN
#
# Sidtime
#
sub GMST0 {
my ($d) = @_;
my $sidtim0 = revolution( ( 180.0 + 356.0470 + 282.9404 )
+ ( 0.9856002585 + 4.70935E-5 ) * $d );
return $sidtim0;
}
#
#
# FUNCTIONAL SEQUENCE for sun_RA_dec
#
# _GIVEN
# day number, $r and $lon (from sunpos)
#
# _THEN
#
# compute RA and dec
#
#
# _RETURN
#
# Sun's Right Ascension (RA), Declination (dec) and distance (r)
#
#
sub sun_RA_dec {
my ($d, $lon_noon, $trace) = @_;
# Compute Sun's ecliptical coordinates
my ( $r, $lon ) = sunpos($d);
if ($trace) {
printf $trace "For day $d (%s), solar noon at ecliptic longitude $lon %s\n", _fmt_hr(24 * ($d - int($d)), $lon_noon), _fmt_angle($lon);
}
# Compute ecliptic rectangular coordinates (z=0)
my $x = $r * cosd($lon);
my $y = $r * sind($lon);
# Compute obliquity of ecliptic (inclination of Earth's axis)
my $obl_ecl = 23.4393 - 3.563E-7 * $d;
# Convert to equatorial rectangular coordinates - x is unchanged
my $z = $y * sind($obl_ecl);
$y = $y * cosd($obl_ecl);
# Convert to spherical coordinates
my $RA = atan2d( $y, $x );
my $dec = atan2d( $z, sqrt( $x * $x + $y * $y ) );
return ( $RA, $dec, $r );
} # sun_RA_dec
#
#
# FUNCTIONAL SEQUENCE for sunpos
#
# _GIVEN
# day number
#
# _THEN
#
# Computes the Sun's ecliptic longitude and distance
# at an instant given in d, number of days since
# 2000 Jan 0.0.
#
#
# _RETURN
#
# ecliptic longitude and distance
# ie. $True_solar_longitude, $Solar_distance
#
sub sunpos {
my ($d) = @_;
# Mean anomaly of the Sun
# Mean longitude of perihelion
# Note: Sun's mean longitude = M + w
# Eccentricity of Earth's orbit
# Eccentric anomaly
# x, y coordinates in orbit
# True anomaly
# Compute mean elements
my $Mean_anomaly_of_sun = revolution( 356.0470 + 0.9856002585 * $d );
my $Mean_longitude_of_perihelion = 282.9404 + 4.70935E-5 * $d;
my $Eccentricity_of_Earth_orbit = 0.016709 - 1.151E-9 * $d;
# Compute true longitude and radius vector
my $Eccentric_anomaly = $Mean_anomaly_of_sun
+ $Eccentricity_of_Earth_orbit * $RADEG
* sind($Mean_anomaly_of_sun)
* ( 1.0 + $Eccentricity_of_Earth_orbit * cosd($Mean_anomaly_of_sun) );
my $x = cosd($Eccentric_anomaly) - $Eccentricity_of_Earth_orbit;
my $y = sqrt( 1.0 - $Eccentricity_of_Earth_orbit * $Eccentricity_of_Earth_orbit )
* sind($Eccentric_anomaly);
my $Solar_distance = sqrt( $x * $x + $y * $y ); # Solar distance
my $True_anomaly = atan2d( $y, $x ); # True anomaly
my $True_solar_longitude = $True_anomaly + $Mean_longitude_of_perihelion; # True solar longitude
if ( $True_solar_longitude >= 360.0 ) {
$True_solar_longitude -= 360.0; # Make it 0..360 degrees
}
return ( $Solar_distance, $True_solar_longitude );
}
sub sind {
sin( ( $_[0] ) * $DEGRAD );
}
sub cosd {
cos( ( $_[0] ) * $DEGRAD );
}
sub tand {
tan( ( $_[0] ) * $DEGRAD );
}
sub atand {
( $RADEG * atan( $_[0] ) );
}
sub asind {
( $RADEG * asin( $_[0] ) );
}
sub acosd {
( $RADEG * acos( $_[0] ) );
}
sub atan2d {
( $RADEG * atan2( $_[0], $_[1] ) );
}
#
#
# FUNCTIONAL SEQUENCE for revolution
#
# _GIVEN
( run in 1.923 second using v1.01-cache-2.11-cpan-98e64b0badf )