package Math::Complex;
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $Inf);
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $Inf $ExpInf);
-$VERSION = 1.52;
+$VERSION = 1.54;
use Config;
if ($^O eq 'unicosmk') {
$Inf = $DBL_MAX;
} else {
+ local $SIG{FPE} = { };
local $!;
# We do want an arithmetic overflow, Inf INF inf Infinity.
for my $t (
'INFINITY',
'1e99999',
) {
- local $SIG{FPE} = { };
local $^W = 0;
my $i = eval "$t+1.0";
if (defined $i && $i > $BIGGER_THAN_THIS) {
$Inf = $DBL_MAX unless defined $Inf; # Oh well, close enough.
die "Math::Complex: Could not get Infinity"
unless $Inf > $BIGGER_THAN_THIS;
+ $ExpInf = exp(99999);
}
# print "# On this machine, Inf = '$Inf'\n";
}
my $ex;
unless (ref $z) {
$ex = CORE::exp($z);
- return $ex ? ($ex + 1/$ex)/2 : Inf();
+ return $ex ? ($ex == $ExpInf ? Inf() : ($ex + 1/$ex)/2) : Inf();
}
my ($x, $y) = @{$z->_cartesian};
$ex = CORE::exp($x);
unless (ref $z) {
return 0 if $z == 0;
$ex = CORE::exp($z);
- return $ex ? ($ex - 1/$ex)/2 : -Inf();
+ return $ex ? ($ex == $ExpInf ? Inf() : ($ex - 1/$ex)/2) : -Inf();
}
my ($x, $y) = @{$z->_cartesian};
my $cy = CORE::cos($y);
#
# acosh
#
-# Computes the arc hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)).
+# Computes the area/inverse hyperbolic cosine acosh(z) = log(z + sqrt(z*z-1)).
#
sub acosh {
my ($z) = @_;
#
# asinh
#
-# Computes the arc hyperbolic sine asinh(z) = log(z + sqrt(z*z+1))
+# Computes the area/inverse hyperbolic sine asinh(z) = log(z + sqrt(z*z+1))
#
sub asinh {
my ($z) = @_;
#
# atanh
#
-# Computes the arc hyperbolic tangent atanh(z) = 1/2 log((1+z) / (1-z)).
+# Computes the area/inverse hyperbolic tangent atanh(z) = 1/2 log((1+z) / (1-z)).
#
sub atanh {
my ($z) = @_;
#
# asech
#
-# Computes the hyperbolic arc secant asech(z) = acosh(1 / z).
+# Computes the area/inverse hyperbolic secant asech(z) = acosh(1 / z).
#
sub asech {
my ($z) = @_;
#
# acsch
#
-# Computes the hyperbolic arc cosecant acsch(z) = asinh(1 / z).
+# Computes the area/inverse hyperbolic cosecant acsch(z) = asinh(1 / z).
#
sub acsch {
my ($z) = @_;
#
# acoth
#
-# Computes the arc hyperbolic cotangent acoth(z) = 1/2 log((1+z) / (z-1)).
+# Computes the area/inverse hyperbolic cotangent acoth(z) = 1/2 log((1+z) / (z-1)).
#
sub acoth {
my ($z) = @_;
use 5.005;
use strict;
-use Math::Complex 1.51;
+use Math::Complex 1.54;
use Math::Complex qw(:trig :pi);
use vars qw($VERSION $PACKAGE @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
@ISA = qw(Exporter);
-$VERSION = 1.16;
+$VERSION = 1.18;
my @angcnv = qw(rad2deg rad2grad
deg2rad deg2grad
return rad2rad($direction);
}
-*great_circle_bearing = \&great_circle_direction;
+*great_circle_bearing = \&great_circle_direction;
sub great_circle_waypoint {
my ( $theta0, $phi0, $theta1, $phi1, $point ) = @_;
my $theta = atan2($y, $x);
my $phi = acos_real($z);
-
+
return ($theta, $phi);
}
my $lat0 = pip2 - $phi0;
- my $phi1 = asin_real(sin($lat0)*cos($dst) +
+ my $phi1 = asin_real(sin($lat0)*cos($dst) +
cos($lat0)*sin($dst)*cos($dir0));
+
my $theta1 = $theta0 + atan2(sin($dir0)*sin($dst)*cos($lat0),
cos($dst)-sin($lat0)*sin($phi1));
B<csch>, B<cosech>, B<sech>, B<coth>, B<cotanh>
-The arcus (also known as the inverse) functions of the hyperbolic
+The area (also known as the inverse) functions of the hyperbolic
sine, cosine, and tangent
B<asinh>, B<acosh>, B<atanh>
-The arcus cofunctions of the hyperbolic sine, cosine, and tangent
+The area cofunctions of the hyperbolic sine, cosine, and tangent
(acsch/acosech and acoth/acotanh are aliases)
B<acsch>, B<acosech>, B<asech>, B<acoth>, B<acotanh>
straight north, pi or -pi straight south, pi/2 straight west, and
-pi/2 straight east.
+=head2 great_circle_destination
+
You can inversely compute the destination if you know the
starting point, direction, and distance:
-=head2 great_circle_destination
-
use Math::Trig 'great_circle_destination';
- # thetad and phid are the destination coordinates,
- # dird is the final direction at the destination.
+ # $diro is the original direction,
+ # for example from great_circle_bearing().
+ # $distance is the angular distance in radians,
+ # for example from great_circle_distance().
+ # $thetad and $phid are the destination coordinates,
+ # $dird is the final direction at the destination.
($thetad, $phid, $dird) =
- great_circle_destination($theta, $phi, $direction, $distance);
+ great_circle_destination($theta, $phi, $diro, $distance);
or the midpoint if you know the end points:
my @M = great_circle_midpoint(@L, @T);
-or about 68.93N 89.16E, in the frozen wastes of Siberia.
+or about 69 N 89 E, in the frozen wastes of Siberia.
+
+B<NOTE>: you B<cannot> get from A to B like this:
+
+ Dist = great_circle_distance(A, B)
+ Dir = great_circle_direction(A, B)
+ C = great_circle_destination(A, Dist, Dir)
+
+and expect C to be B, because the bearing constantly changes when
+going from A to B (except in some special case like the meridians or
+the circles of latitudes) and in great_circle_destination() one gives
+a constant bearing to follow.
=head2 CAVEAT FOR GREAT CIRCLE FORMULAS