require Exporter;
package Math::Trig;
use strict;
use Math::Complex qw(:trig);
use vars qw($VERSION $PACKAGE
  @ISA
  @EXPORT @EXPORT_OK %EXPORT_TAGS);
@ISA=qw(Exporter);
$VERSION = 1.00;
my@angcnv=qw(rad2deg rad2grad
  deg2rad deg2grad
  grad2rad grad2deg);
@EXPORT=(@{$Math::Complex::EXPORT_TAGS{'trig'}},@angcnv);
my@rdlcnv=qw(cartesian_to_cylindrical
  cartesian_to_spherical
  cylindrical_to_cartesian
  cylindrical_to_spherical
  spherical_to_cartesian
  spherical_to_cylindrical);
@EXPORT_OK=(@rdlcnv,'great_circle_distance');
%EXPORT_TAGS=('radial'=>[@rdlcnv]);
use constant pi2=>2*pi;
use constant pip2=>pi/2;
use constant DR=>pi2/360;
use constant RD=>360/pi2;
use constant DG=>400/360;
use constant GD=>360/400;
use constant RG=>400/pi2;
use constant GR=>pi2/400;
sub remt ($$){$_[0]-$_[1]*int($_[0]/$_[1]);}sub rad2deg ($){remt(RD*$_[0],360)}sub deg2rad ($){remt(DR*$_[0],pi2)}sub grad2deg ($){remt(GD*$_[0],360)}sub deg2grad ($){remt(DG*$_[0],400)}sub rad2grad ($){remt(RG*$_[0],400)}sub grad2rad ($){remt(GR*$_[0],pi2)}sub cartesian_to_spherical{my($x,$y,$z)=@_;
my$rho=sqrt($x*$x+$y*$y+$z*$z);
return($rho,atan2($y,$x),$rho?acos($z/$rho):0);}sub spherical_to_cartesian{my($rho,$theta,$phi)=@_;
return($rho*cos($theta)*sin($phi),$rho*sin($theta)*sin($phi),$rho*cos($phi));}sub spherical_to_cylindrical{my($x,$y,$z)=spherical_to_cartesian(@_);
return(sqrt($x*$x+$y*$y),$_[1],$z);}sub cartesian_to_cylindrical{my($x,$y,$z)=@_;
return(sqrt($x*$x+$y*$y),atan2($y,$x),$z);}sub cylindrical_to_cartesian{my($rho,$theta,$z)=@_;
return($rho*cos($theta),$rho*sin($theta),$z);}sub cylindrical_to_spherical{return(cartesian_to_spherical(cylindrical_to_cartesian(@_)));}sub great_circle_distance{my($theta0,$phi0,$theta1,$phi1,$rho)=@_;
$rho=1 unless defined$rho;
my$lat0=pip2-$phi0;
my$lat1=pip2-$phi1;
return$rho*acos(cos($lat0)*cos($lat1)*cos($theta0-$theta1)+sin($lat0)*sin($lat1));}
