Astro-Coords
view release on metacpan or search on metacpan
lib/Astro/Coords/Angle.pm view on Meta::CPAN
package Astro::Coords::Angle;
=head1 NAME
Astro::Coords::Angle - Representation of an angle
=head1 SYNOPSIS
use Astro::Coords::Angle;
$ang = new Astro::Coords::Angle( 45.5, units => 'deg' );
$ang = new Astro::Coords::Angle( "45:30:00", units => 'sexagesimal' );
$rad = $ang->radians;
$deg = $ang->degrees;
$asec = $ang->arcsec;
$amin = $ang->arcmin;
$string = $ang->string;
=head1 DESCRIPTION
Helper class for C<Astro::Coords> to represent an angle. Methods are
provided for parsing angles in sexagesimal format and for returning
angles in any desired format.
=cut
use 5.006;
use strict;
use warnings;
use warnings::register;
use Carp;
use Scalar::Util qw/ looks_like_number /;
use Astro::PAL;
# Overloading
use overload
'""' => "stringify",
'0+' => "numify",
fallback => 1;
# Package Global variables
our $VERSION = '0.23';
=head1 METHODS
=head2 Constructor
=over 4
=item B<new>
Construct a new C<Angle> object. Must be called with an angle as first
argument. Optional hash arguments can be supplied to specify, for example,
the units of the supplied angle.
$ang = new Astro::Coords::Angle( $angle,
units => "degrees" );
Supported options are:
units - units of the supplied string or number
range - restricted range of the angle
Supported units are:
sexagesimal - A string of format either dd:mm:ss or "dd mm ss"
"dms" separators are also supported.
degrees - decimal degrees
radians - radians
arcsec - arc seconds (abbreviated form is 'as')
arcmin - arc minutes (abbreviated form is 'am')
The units can be abbreviated to the first 3 characters.
If the units are not supplied the default is to assume "sexagesimal"
if the supplied string contains spaces or colons or the characters
"d", "m" or "s", "degrees" if the supplied number is greater than 2*PI
(6.28), and "radians" for all other values. Negative angles are supported.
The options for range are documented in the C<range> method.
If the angle can not be decoded (if a string), the constructor will fail.
=cut
sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
croak "Constructor for object of class $class must be called with an argument" unless @_;
# first argument is the angle
lib/Astro/Coords/Angle.pm view on Meta::CPAN
my $nstrt = 1;
($nstrt, $output, my $j) = Astro::PAL::palDafin( $input, $nstrt );
$output = undef unless $j == 0;
if ($j == -1) {
warnings::warnif "In coordinate '$input' the degrees do not look right";
} elsif ($j == -2) {
warnings::warnif "In coordinate '$input' the minutes field is out of range";
} elsif ($j == -3) {
warnings::warnif "In coordinate '$input' the seconds field is out of range (0-59.9)";
} elsif ($j == 1) {
warnings::warnif "Unable to find plausible coordinate in string '$input'";
}
} elsif ($units =~ /^d/) {
# Degrees decimal
$output = $input * Astro::PAL::DD2R;
} elsif ($units =~ /^arcs/ || $units eq 'as') {
# Arcsec
$output = $input * Astro::PAL::DAS2R;
} elsif ($units =~ /^arcm/ || $units eq 'am') {
# Arcmin
$output = $input * Astro::PAL::DAS2R * 60 ;
} else {
# Already in radians
$output = $input;
}
return $output;
}
=item B<_guess_units>
Given a string or number, tries to guess the units. Default is to
assume "sexagesimal" if the supplied string does not look like a
number to perl, "degrees" if the supplied number is greater than 2*PI
(6.28), and "radians" for all other values.
$units = $class->_guess_units( $input );
Returns undef if the input does not look at all plausible or is undef
itself.
Arcsec or arcmin can not be determined with this routine.
=cut
sub _guess_units {
my $self = shift;
my $input = shift;
return undef if !defined $input;
# Now if we have a space, colon or alphabetic character
# then we have a real string and assume sexagesimal.
# Use pre-defined character classes
my $units;
# if it does not look like a number choose sexagesimal
if (!looks_like_number($input)) {
$units = "sexagesimal";
} elsif ($input > Astro::PAL::D2PI) {
$units = "degrees";
} else {
$units = "radians";
}
return $units;
}
=item B<_r2f>
Routine to convert angle in radians to a formatted array
of numbers in order of sign, deg, min, sec, frac.
@retval = $ang->_r2f( $ndp );
Note that the number of decimal places is an argument.
=cut
sub _r2f {
my $self = shift;
my $res = shift;
warnings::warnif("More than 9 dp requested ($res), result from palDr2af likely to overflow in fractional part") if $res > 9;
my ($sign, @dmsf) = Astro::PAL::palDr2af($res, $self->radians);
return ($sign, @dmsf);
}
=back
=end __PRIVATE_METHODS__
=head1 AUTHOR
Tim Jenness E<lt>t.jenness@cpan.orgE<gt>
=head1 COPYRIGHT
Copyright (C) 2004-2005 Tim Jenness. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful,but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place,Suite 330, Boston, MA 02111-1307, USA
=cut
1;
( run in 2.387 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )