Astro-Coord-ECI-VSOP87D

 view release on metacpan or  search on metacpan

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

package Astro::Coord::ECI::VSOP87D::Sun;

use 5.008;

use strict;
use warnings;

use base qw{ Astro::Coord::ECI::Sun };

use Astro::Coord::ECI::Mixin qw{ next_quarter };

use Astro::Coord::ECI::VSOP87D qw{ :sun };

use Carp;

our $VERSION = '0.008';

sub new {
    my ( $class, %arg ) = @_;
    $class->__default( \%arg );
    return $class->SUPER::new( %arg );
}

{
    my $get = sub {
	my ( $self, $name ) = @_;
	return $self->__get_attr()->{$name};
    };

    my %accessor = (
	model_cutoff		=> $get,
	nutation_cutoff		=> $get,
    );

    sub attribute {
	my ( $self, $name ) = @_;
	exists $accessor{$name}
	    and return __PACKAGE__;
	return $self->SUPER::attribute( $name );
    }

    sub get {
	my ( $self, @arg ) = @_;
	my @rslt;
	foreach my $name ( @arg ) {
	    if ( my $code = $accessor{$name} ) {
		push @rslt, $code->( $self, $name );
	    } else {
		push @rslt, $self->SUPER::get( $name );
	    }
	    wantarray
		or return $rslt[0];
	}
	return @rslt;
    }
}

sub __model {
    return ( ( 0 ) x 6 );
}

# NOTE that we are using the Sun to carry the model definition for the
# Earth. This works because we override __model().
sub __model_definition {
    my ( undef, $key ) = @_;
    return {
      body => "Sun",
      default_model_cutoff => {
        Meeus => {
                   B0   => 5,
                   B1   => 1,
                   L0   => 64,
                   L1   => 34,
                   L2   => 20,
                   L3   => 7,
                   L4   => 3,
                   L5   => 1,
                   name => "Meeus",
                   R0   => 40,
                   R1   => 10,
                   R2   => 6,
                   R3   => 2,
                   R4   => 1,
                 },
        none  => {
                   B0   => 184,
                   B1   => 99,
                   B2   => 49,
                   B3   => 11,
                   B4   => 5,
                   L0   => 559,
                   L1   => 341,
                   L2   => 142,
                   L3   => 22,
                   L4   => 11,
                   L5   => 5,
                   name => "none",
                   R0   => 526,
                   R1   => 292,
                   R2   => 139,
                   R3   => 27,
                   R4   => 10,
                   R5   => 3,
                 },
      },
      diameter => 1_391_016,	# https://solarsystem.nasa.gov/solar-system/sun/in-depth/
      model => [
        [
          {

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

                        [1.1e-10, 1.37795688024, 6309.3741697912],
                        [1e-10, 5.19937959068, 71430.6956181291],
                        [9e-11, 0.4727519993, 6279.5527316424],
                        [9e-11, 0.74642756529, 5729.506447149],
                        [7e-11, 2.9737489156, 775.522611324],
                        [7e-11, 3.28615691021, 7058.5984613154],
                        [7e-11, 2.19184402142, 6812.766815086],
                        [5e-11, 3.15419034438, 529.6909650946],
                        [6e-11, 4.54725567047, 1059.3819301892],
                        [5e-11, 1.51104406936, 7079.3738568078],
                        [7e-11, 2.98052059053, 6681.2248533996],
                        [5e-11, 2.30961231391, 12036.4607348882],
                        [5e-11, 3.71102966917, 6290.1893969922],
                      ],
          },
          {
            series => "R4",
            terms  => [
                        [3.858e-08, 2.56384387339, 6283.0758499914],
                        [3.06e-09, 2.2676950123, 12566.1516999828],
                        [5.3e-10, 3.44031471924, 5573.1428014331],
                        [1.5e-10, 2.04794573436, 18849.2275499742],
                        [1.3e-10, 2.05688873673, 77713.7714681205],
                        [7e-11, 4.4121885448, 161000.685737674],
                        [5e-11, 5.26154653107, 6438.4962494256],
                        [5e-11, 4.07695126049, 6127.6554505572],
                        [6e-11, 3.81514213664, 149854.400134808],
                        [3e-11, 1.28175749811, 6286.5989683404],
                      ],
          },
          {
            series => "R5",
            terms  => [
                        [8.6e-10, 1.21579741687, 6283.0758499914],
                        [1.2e-10, 0.65617264033, 12566.1516999828],
                        [1e-11, 0.38068797142, 18849.2275499742],
                      ],
          },
        ],
      ],
      name => "VSOP87D",
      order => 0,
      sidereal_period => 31558149.764,
      tropical_period => 31556925.183,
    }->{$key};
}

{
    my %mutator = (
	model_cutoff		=> \&__mutate_model_cutoff,
	nutation_cutoff		=> \&__mutate_nutation_cutoff,
    );

    sub set {
	my ( $self, @arg ) = @_;
	while ( @arg ) {
	    my ( $name, $value ) = splice @arg, 0, 2;
	    if ( my $code = $mutator{$name} ) {
		$code->( $self, $name, $value );
	    } else {
		$self->SUPER::set( $name, $value );
	    }
	}
	return $self;
    }
}

1;

__END__

=head1 NAME

Astro::Coord::ECI::VSOP87D::Sun - VSOP87D model of the position of the Sun

=head1 SYNOPSIS

 use Astro::Coord::ECI::VSOP87D::Sun;
 use Astro::Coord::ECI::Utils qw{ deg2rad };
 use POSIX qw{ strftime };
 use Time::Local qw{ localtime };
 
 my $station = Astro::Coord::ECI->new(
     name => 'White House',
 )->geodetic(
     deg2rad( 38.899 ),  # radians
     deg2rad( -77.038 ), # radians
     16.68/1000,         # Kilometers
 );
 my $sun = Astro::Coord::ECI::VSOP87D::Sun->new(
     station => $station,
 );
 my $today = timelocal( 0, 0, 0, ( localtime )[ 3 .. 5 ] );
 foreach my $item ( $sun->almanac( $today, $today + 86400 ) ) {
     local $\ = "\n";
     print strftime( '%d-%b-%Y %H:%M:%S', localtime $item->[0] ),
         $item->[3];
 }

=head1 DESCRIPTION

This Perl class computes the position of the Sun using the VSOP87D
model. It is a subclass of
L<Astro::Coord::ECI::Sun|Astro::Coord::ECI::Sun>.

=head1 METHODS

This class supports the following public methods in addition to those of
its superclass:

=head2 geometric_longitude

This method returns the geometric longitude of the body. This is after
conversion to FK5.

=head2 model_cutoff_definition

This method reports, creates, and deletes model cutoff definitions.

The first argument is the name of the model cutoff. If this is the only
argument, a reference to a hash defining the named model cutoff is



( run in 0.965 second using v1.01-cache-2.11-cpan-d80b1682f3f )