1#
2# Trigonometric functions, mostly inherited from Math::Complex.
3# -- Jarkko Hietaniemi, since April 1997
4# -- Raphael Manfredi, September 1996 (indirectly: because of Math::Complex)
5#
6
7package Math::Trig;
8
9{ use 5.006; }
10use strict;
11
12use Math::Complex 1.59;
13use Math::Complex qw(:trig :pi);
14require Exporter;
15
16our @ISA = qw(Exporter);
17
18our $VERSION = 1.62;
19
20my @angcnv = qw(rad2deg rad2grad
21		deg2rad deg2grad
22		grad2rad grad2deg);
23
24my @areal = qw(asin_real acos_real);
25
26our @EXPORT = (@{$Math::Complex::EXPORT_TAGS{'trig'}},
27	   @angcnv, @areal);
28
29my @rdlcnv = qw(cartesian_to_cylindrical
30		cartesian_to_spherical
31		cylindrical_to_cartesian
32		cylindrical_to_spherical
33		spherical_to_cartesian
34		spherical_to_cylindrical);
35
36my @greatcircle = qw(
37		     great_circle_distance
38		     great_circle_direction
39		     great_circle_bearing
40		     great_circle_waypoint
41		     great_circle_midpoint
42		     great_circle_destination
43		    );
44
45my @pi = qw(pi pi2 pi4 pip2 pip4);
46
47our @EXPORT_OK = (@rdlcnv, @greatcircle, @pi, 'Inf');
48
49# See e.g. the following pages:
50# https://www.movable-type.co.uk/scripts/latlong.html
51# https://edwilliams.org/avform.htm
52# https://en.wikipedia.org/wiki/Great-circle_distance
53
54our %EXPORT_TAGS = ('radial' => [ @rdlcnv ],
55	        'great_circle' => [ @greatcircle ],
56	        'pi'     => [ @pi ]);
57
58sub _DR  () { pi2/360 }
59sub _RD  () { 360/pi2 }
60sub _DG  () { 400/360 }
61sub _GD  () { 360/400 }
62sub _RG  () { 400/pi2 }
63sub _GR  () { pi2/400 }
64
65#
66# Truncating remainder.
67#
68
69sub _remt ($$) {
70    # Oh yes, POSIX::fmod() would be faster. Possibly. If it is available.
71    $_[0] - $_[1] * int($_[0] / $_[1]);
72}
73
74#
75# Angle conversions.
76#
77
78sub rad2rad($)     { _remt($_[0], pi2) }
79
80sub deg2deg($)     { _remt($_[0], 360) }
81
82sub grad2grad($)   { _remt($_[0], 400) }
83
84sub rad2deg ($;$)  { my $d = _RD * $_[0]; $_[1] ? $d : deg2deg($d) }
85
86sub deg2rad ($;$)  { my $d = _DR * $_[0]; $_[1] ? $d : rad2rad($d) }
87
88sub grad2deg ($;$) { my $d = _GD * $_[0]; $_[1] ? $d : deg2deg($d) }
89
90sub deg2grad ($;$) { my $d = _DG * $_[0]; $_[1] ? $d : grad2grad($d) }
91
92sub rad2grad ($;$) { my $d = _RG * $_[0]; $_[1] ? $d : grad2grad($d) }
93
94sub grad2rad ($;$) { my $d = _GR * $_[0]; $_[1] ? $d : rad2rad($d) }
95
96#
97# acos and asin functions which always return a real number
98#
99
100sub acos_real {
101    return 0  if $_[0] >=  1;
102    return pi if $_[0] <= -1;
103    return acos($_[0]);
104}
105
106sub asin_real {
107    return  &pip2 if $_[0] >=  1;
108    return -&pip2 if $_[0] <= -1;
109    return asin($_[0]);
110}
111
112sub cartesian_to_spherical {
113    my ( $x, $y, $z ) = @_;
114
115    my $rho = sqrt( $x * $x + $y * $y + $z * $z );
116
117    return ( $rho,
118             atan2( $y, $x ),
119             $rho ? acos_real( $z / $rho ) : 0 );
120}
121
122sub spherical_to_cartesian {
123    my ( $rho, $theta, $phi ) = @_;
124
125    return ( $rho * cos( $theta ) * sin( $phi ),
126             $rho * sin( $theta ) * sin( $phi ),
127             $rho * cos( $phi   ) );
128}
129
130sub spherical_to_cylindrical {
131    my ( $x, $y, $z ) = spherical_to_cartesian( @_ );
132
133    return ( sqrt( $x * $x + $y * $y ), $_[1], $z );
134}
135
136sub cartesian_to_cylindrical {
137    my ( $x, $y, $z ) = @_;
138
139    return ( sqrt( $x * $x + $y * $y ), atan2( $y, $x ), $z );
140}
141
142sub cylindrical_to_cartesian {
143    my ( $rho, $theta, $z ) = @_;
144
145    return ( $rho * cos( $theta ), $rho * sin( $theta ), $z );
146}
147
148sub cylindrical_to_spherical {
149    return ( cartesian_to_spherical( cylindrical_to_cartesian( @_ ) ) );
150}
151
152sub great_circle_distance {
153    my ( $theta0, $phi0, $theta1, $phi1, $rho ) = @_;
154
155    $rho = 1 unless defined $rho; # Default to the unit sphere.
156
157    my $dphi   = $phi1 - $phi0;
158    my $dtheta = $theta1 - $theta0;
159
160    # A formula that is accurate for all distances is the following special
161    # case of the Vincenty formula for an ellipsoid with equal major and minor
162    # axes.  See
163    # https://en.wikipedia.org/wiki/Great-circle_distance#Computational_formulas
164
165    my $c1 = sin($phi1) * sin($dtheta);
166    my $c2 = sin($phi1) * cos($dtheta);
167    my $c3 = sin($phi0) * cos($phi1) - cos($phi0) * $c2;
168    my $c4 = cos($phi0) * cos($phi1) + sin($phi0) * $c2;
169    return $rho * atan2(sqrt($c1 * $c1 + $c3 * $c3), $c4);
170}
171
172sub great_circle_direction {
173    my ( $theta0, $phi0, $theta1, $phi1 ) = @_;
174
175    my $lat0 = pip2 - $phi0;
176    my $lat1 = pip2 - $phi1;
177
178    return rad2rad(pi2 -
179	atan2(sin($theta0-$theta1) * cos($lat1),
180		cos($lat0) * sin($lat1) -
181		    sin($lat0) * cos($lat1) * cos($theta0-$theta1)));
182}
183
184*great_circle_bearing         = \&great_circle_direction;
185
186sub great_circle_waypoint {
187    my ( $theta0, $phi0, $theta1, $phi1, $point ) = @_;
188
189    $point = 0.5 unless defined $point;
190
191    my $d = great_circle_distance( $theta0, $phi0, $theta1, $phi1 );
192
193    return undef if $d == pi;
194
195    my $sd = sin($d);
196
197    return ($theta0, $phi0) if $sd == 0;
198
199    my $A = sin((1 - $point) * $d) / $sd;
200    my $B = sin(     $point  * $d) / $sd;
201
202    my $lat0 = pip2 - $phi0;
203    my $lat1 = pip2 - $phi1;
204
205    my $x = $A * cos($lat0) * cos($theta0) + $B * cos($lat1) * cos($theta1);
206    my $y = $A * cos($lat0) * sin($theta0) + $B * cos($lat1) * sin($theta1);
207    my $z = $A * sin($lat0)                + $B * sin($lat1);
208
209    my $theta = atan2($y, $x);
210    my $phi   = acos_real($z);
211
212    return ($theta, $phi);
213}
214
215sub great_circle_midpoint {
216    great_circle_waypoint(@_[0..3], 0.5);
217}
218
219sub great_circle_destination {
220    my ( $theta0, $phi0, $dir0, $dst ) = @_;
221
222    my $lat0 = pip2 - $phi0;
223
224    my $phi1   = asin_real(sin($lat0)*cos($dst) +
225			   cos($lat0)*sin($dst)*cos($dir0));
226
227    my $theta1 = $theta0 + atan2(sin($dir0)*sin($dst)*cos($lat0),
228				 cos($dst)-sin($lat0)*sin($phi1));
229
230    my $dir1 = great_circle_bearing($theta1, $phi1, $theta0, $phi0) + pi;
231
232    $dir1 -= pi2 if $dir1 > pi2;
233
234    return ($theta1, $phi1, $dir1);
235}
236
2371;
238
239__END__
240=pod
241
242=head1 NAME
243
244Math::Trig - trigonometric functions
245
246=head1 SYNOPSIS
247
248    use Math::Trig;
249
250    $x = tan(0.9);
251    $y = acos(3.7);
252    $z = asin(2.4);
253
254    $halfpi = pi/2;
255
256    $rad = deg2rad(120);
257
258    # Import constants pi2, pi4, pip2, pip4 (2*pi, 4*pi, pi/2, pi/4).
259    use Math::Trig ':pi';
260
261    # Import the conversions between cartesian/spherical/cylindrical.
262    use Math::Trig ':radial';
263
264        # Import the great circle formulas.
265    use Math::Trig ':great_circle';
266
267=head1 DESCRIPTION
268
269C<Math::Trig> defines many trigonometric functions not defined by the
270core Perl which defines only the C<sin()> and C<cos()>.  The constant
271B<pi> is also defined as are a few convenience functions for angle
272conversions, and I<great circle formulas> for spherical movement.
273
274=head1 TRIGONOMETRIC FUNCTIONS
275
276The tangent
277
278=over 4
279
280=item B<tan>
281
282=back
283
284The cofunctions of the sine, cosine, and tangent (cosec/csc and cotan/cot
285are aliases)
286
287B<csc>, B<cosec>, B<sec>, B<sec>, B<cot>, B<cotan>
288
289The arcus (also known as the inverse) functions of the sine, cosine,
290and tangent
291
292B<asin>, B<acos>, B<atan>
293
294The principal value of the arc tangent of y/x
295
296B<atan2>(y, x)
297
298The arcus cofunctions of the sine, cosine, and tangent (acosec/acsc
299and acotan/acot are aliases).  Note that atan2(0, 0) is not well-defined.
300
301B<acsc>, B<acosec>, B<asec>, B<acot>, B<acotan>
302
303The hyperbolic sine, cosine, and tangent
304
305B<sinh>, B<cosh>, B<tanh>
306
307The cofunctions of the hyperbolic sine, cosine, and tangent (cosech/csch
308and cotanh/coth are aliases)
309
310B<csch>, B<cosech>, B<sech>, B<coth>, B<cotanh>
311
312The area (also known as the inverse) functions of the hyperbolic
313sine, cosine, and tangent
314
315B<asinh>, B<acosh>, B<atanh>
316
317The area cofunctions of the hyperbolic sine, cosine, and tangent
318(acsch/acosech and acoth/acotanh are aliases)
319
320B<acsch>, B<acosech>, B<asech>, B<acoth>, B<acotanh>
321
322The trigonometric constant B<pi> and some of handy multiples
323of it are also defined.
324
325B<pi, pi2, pi4, pip2, pip4>
326
327=head2 ERRORS DUE TO DIVISION BY ZERO
328
329The following functions
330
331    acoth
332    acsc
333    acsch
334    asec
335    asech
336    atanh
337    cot
338    coth
339    csc
340    csch
341    sec
342    sech
343    tan
344    tanh
345
346cannot be computed for all arguments because that would mean dividing
347by zero or taking logarithm of zero. These situations cause fatal
348runtime errors looking like this
349
350    cot(0): Division by zero.
351    (Because in the definition of cot(0), the divisor sin(0) is 0)
352    Died at ...
353
354or
355
356    atanh(-1): Logarithm of zero.
357    Died at...
358
359For the C<csc>, C<cot>, C<asec>, C<acsc>, C<acot>, C<csch>, C<coth>,
360C<asech>, C<acsch>, the argument cannot be C<0> (zero).  For the
361C<atanh>, C<acoth>, the argument cannot be C<1> (one).  For the
362C<atanh>, C<acoth>, the argument cannot be C<-1> (minus one).  For the
363C<tan>, C<sec>, C<tanh>, C<sech>, the argument cannot be I<pi/2 + k *
364pi>, where I<k> is any integer.
365
366Note that atan2(0, 0) is not well-defined.
367
368=head2 SIMPLE (REAL) ARGUMENTS, COMPLEX RESULTS
369
370Please note that some of the trigonometric functions can break out
371from the B<real axis> into the B<complex plane>. For example
372C<asin(2)> has no definition for plain real numbers but it has
373definition for complex numbers.
374
375In Perl terms this means that supplying the usual Perl numbers (also
376known as scalars, please see L<perldata>) as input for the
377trigonometric functions might produce as output results that no more
378are simple real numbers: instead they are complex numbers.
379
380The C<Math::Trig> handles this by using the C<Math::Complex> package
381which knows how to handle complex numbers, please see L<Math::Complex>
382for more information. In practice you need not to worry about getting
383complex numbers as results because the C<Math::Complex> takes care of
384details like for example how to display complex numbers. For example:
385
386    print asin(2), "\n";
387
388should produce something like this (take or leave few last decimals):
389
390    1.5707963267949-1.31695789692482i
391
392That is, a complex number with the real part of approximately C<1.571>
393and the imaginary part of approximately C<-1.317>.
394
395=head1 PLANE ANGLE CONVERSIONS
396
397(Plane, 2-dimensional) angles may be converted with the following functions.
398
399=over
400
401=item deg2rad
402
403    $radians  = deg2rad($degrees);
404
405=item grad2rad
406
407    $radians  = grad2rad($gradians);
408
409=item rad2deg
410
411    $degrees  = rad2deg($radians);
412
413=item grad2deg
414
415    $degrees  = grad2deg($gradians);
416
417=item deg2grad
418
419    $gradians = deg2grad($degrees);
420
421=item rad2grad
422
423    $gradians = rad2grad($radians);
424
425=back
426
427The full circle is 2 I<pi> radians or I<360> degrees or I<400> gradians.
428The result is by default wrapped to be inside the [0, {2pi,360,400}] circle.
429If you don't want this, supply a true second argument:
430
431    $zillions_of_radians  = deg2rad($zillions_of_degrees, 1);
432    $negative_degrees     = rad2deg($negative_radians, 1);
433
434You can also do the wrapping explicitly by rad2rad(), deg2deg(), and
435grad2grad().
436
437=over 4
438
439=item rad2rad
440
441    $radians_wrapped_by_2pi = rad2rad($radians);
442
443=item deg2deg
444
445    $degrees_wrapped_by_360 = deg2deg($degrees);
446
447=item grad2grad
448
449    $gradians_wrapped_by_400 = grad2grad($gradians);
450
451=back
452
453=head1 RADIAL COORDINATE CONVERSIONS
454
455B<Radial coordinate systems> are the B<spherical> and the B<cylindrical>
456systems, explained shortly in more detail.
457
458You can import radial coordinate conversion functions by using the
459C<:radial> tag:
460
461    use Math::Trig ':radial';
462
463    ($rho, $theta, $z)     = cartesian_to_cylindrical($x, $y, $z);
464    ($rho, $theta, $phi)   = cartesian_to_spherical($x, $y, $z);
465    ($x, $y, $z)           = cylindrical_to_cartesian($rho, $theta, $z);
466    ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);
467    ($x, $y, $z)           = spherical_to_cartesian($rho, $theta, $phi);
468    ($rho_c, $theta, $z)   = spherical_to_cylindrical($rho_s, $theta, $phi);
469
470B<All angles are in radians>.
471
472=head2 COORDINATE SYSTEMS
473
474B<Cartesian> coordinates are the usual rectangular I<(x, y, z)>-coordinates.
475
476Spherical coordinates, I<(rho, theta, phi)>, are three-dimensional
477coordinates which define a point in three-dimensional space.  They are
478based on a sphere surface.  The radius of the sphere is B<rho>, also
479known as the I<radial> coordinate.  The angle in the I<xy>-plane
480(around the I<z>-axis) is B<theta>, also known as the I<azimuthal>
481coordinate.  The angle from the I<z>-axis is B<phi>, also known as the
482I<polar> coordinate.  The North Pole is therefore I<rho, 0, 0>, and
483the Gulf of Guinea (think of the missing big chunk of Africa) I<rho,
4840, pi/2>.  In geographical terms I<phi> is latitude (northward
485positive, southward negative) and I<theta> is longitude (eastward
486positive, westward negative).
487
488B<BEWARE>: some texts define I<theta> and I<phi> the other way round,
489some texts define the I<phi> to start from the horizontal plane, some
490texts use I<r> in place of I<rho>.
491
492Cylindrical coordinates, I<(rho, theta, z)>, are three-dimensional
493coordinates which define a point in three-dimensional space.  They are
494based on a cylinder surface.  The radius of the cylinder is B<rho>,
495also known as the I<radial> coordinate.  The angle in the I<xy>-plane
496(around the I<z>-axis) is B<theta>, also known as the I<azimuthal>
497coordinate.  The third coordinate is the I<z>, pointing up from the
498B<theta>-plane.
499
500=head2 3-D ANGLE CONVERSIONS
501
502Conversions to and from spherical and cylindrical coordinates are
503available.  Please notice that the conversions are not necessarily
504reversible because of the equalities like I<pi> angles being equal to
505I<-pi> angles.
506
507=over 4
508
509=item cartesian_to_cylindrical
510
511    ($rho, $theta, $z) = cartesian_to_cylindrical($x, $y, $z);
512
513=item cartesian_to_spherical
514
515    ($rho, $theta, $phi) = cartesian_to_spherical($x, $y, $z);
516
517=item cylindrical_to_cartesian
518
519    ($x, $y, $z) = cylindrical_to_cartesian($rho, $theta, $z);
520
521=item cylindrical_to_spherical
522
523    ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);
524
525Notice that when C<$z> is not 0 C<$rho_s> is not equal to C<$rho_c>.
526
527=item spherical_to_cartesian
528
529    ($x, $y, $z) = spherical_to_cartesian($rho, $theta, $phi);
530
531=item spherical_to_cylindrical
532
533    ($rho_c, $theta, $z) = spherical_to_cylindrical($rho_s, $theta, $phi);
534
535Notice that when C<$z> is not 0 C<$rho_c> is not equal to C<$rho_s>.
536
537=back
538
539=head1 GREAT CIRCLE DISTANCES AND DIRECTIONS
540
541A great circle is section of a circle that contains the circle
542diameter: the shortest distance between two (non-antipodal) points on
543the spherical surface goes along the great circle connecting those two
544points.
545
546=head2 great_circle_distance
547
548Returns the great circle distance between two points on a sphere.
549
550    $distance = great_circle_distance($theta0, $phi0, $theta1, $phi1, [, $rho]);
551
552Where ($theta0, $phi0) and ($theta1, $phi1) are the spherical coordinates of
553the two points, respectively. The distance is in C<$rho> units. The C<$rho>
554is optional. It defaults to 1 (the unit sphere).
555
556If you are using geographic coordinates, latitude and longitude, you need to
557adjust for the fact that latitude is zero at the equator increasing towards
558the north and decreasing towards the south. Assuming ($lat0, $lon0) and
559($lat1, $lon1) are the geographic coordinates in radians of the two points,
560the distance can be computed with
561
562  $distance = great_circle_distance($lon0, pi/2 - $lat0,
563                                    $lon1, pi/2 - $lat1, $rho);
564
565=head2 great_circle_direction
566
567The direction you must follow the great circle (also known as I<bearing>)
568can be computed by the great_circle_direction() function:
569
570  use Math::Trig 'great_circle_direction';
571
572  $direction = great_circle_direction($theta0, $phi0, $theta1, $phi1);
573
574=head2 great_circle_bearing
575
576Alias 'great_circle_bearing' for 'great_circle_direction' is also available.
577
578  use Math::Trig 'great_circle_bearing';
579
580  $direction = great_circle_bearing($theta0, $phi0, $theta1, $phi1);
581
582The result of great_circle_direction is in radians, zero indicating
583straight north, pi or -pi straight south, pi/2 straight west, and
584-pi/2 straight east.
585
586=head2 great_circle_destination
587
588You can inversely compute the destination if you know the
589starting point, direction, and distance:
590
591  use Math::Trig 'great_circle_destination';
592
593  # $diro is the original direction,
594  # for example from great_circle_bearing().
595  # $distance is the angular distance in radians,
596  # for example from great_circle_distance().
597  # $thetad and $phid are the destination coordinates,
598  # $dird is the final direction at the destination.
599
600  ($thetad, $phid, $dird) =
601    great_circle_destination($theta, $phi, $diro, $distance);
602
603or the midpoint if you know the end points:
604
605=head2 great_circle_midpoint
606
607  use Math::Trig 'great_circle_midpoint';
608
609  ($thetam, $phim) =
610    great_circle_midpoint($theta0, $phi0, $theta1, $phi1);
611
612The great_circle_midpoint() is just a special case of
613
614=head2 great_circle_waypoint
615
616  use Math::Trig 'great_circle_waypoint';
617
618  ($thetai, $phii) =
619    great_circle_waypoint($theta0, $phi0, $theta1, $phi1, $way);
620
621Where $way indicates the position of the waypoint along the great
622circle arc through the starting point ($theta0, $phi0) and the end
623point ($theta1, $phi1) relative to the distance from the starting
624point to the end point. So $way = 0 gives the starting point, $way = 1
625gives the end point, $way < 0 gives a point "behind" the starting
626point, and $way > 1 gives a point beyond the end point. $way defaults
627to 0.5 if not given.
628
629Note that antipodal points (where their distance is I<pi> radians) do
630not have unique waypoints between them, and therefore C<undef> is
631returned in such cases.  If the points are the same, so the distance
632between them is zero, all waypoints are identical to the starting/end
633point.
634
635The thetas, phis, direction, and distance in the above are all in
636radians.
637
638You can import all the great circle formulas by
639
640  use Math::Trig ':great_circle';
641
642Notice that the resulting directions might be somewhat surprising if
643you are looking at a flat worldmap: in such map projections the great
644circles quite often do not look like the shortest routes --  but for
645example the shortest possible routes from Europe or North America to
646Asia do often cross the polar regions.  (The common Mercator projection
647does B<not> show great circles as straight lines: straight lines in the
648Mercator projection are lines of constant bearing.)
649
650=head1 EXAMPLES
651
652To calculate the distance between London (51.3N 0.5W) and Tokyo
653(35.7N 139.8E) in kilometers:
654
655    use Math::Trig qw(great_circle_distance deg2rad);
656
657    # Notice the 90 - latitude: phi zero is at the North Pole.
658    sub NESW { deg2rad($_[0]), deg2rad(90 - $_[1]) }
659    my @L = NESW( -0.5, 51.3);
660    my @T = NESW(139.8, 35.7);
661    my $km = great_circle_distance(@L, @T, 6378); # About 9600 km.
662
663The direction you would have to go from London to Tokyo (in radians,
664straight north being zero, straight east being pi/2).
665
666    use Math::Trig qw(great_circle_direction);
667
668    my $rad = great_circle_direction(@L, @T); # About 0.547 or 0.174 pi.
669
670The midpoint between London and Tokyo being
671
672    use Math::Trig qw(great_circle_midpoint rad2deg);
673
674    my @M = great_circle_midpoint(@L, @T);
675    sub SWNE { rad2deg( $_[0] ), 90 - rad2deg( $_[1] ) }
676    my @lonlat = SWNE(@M);
677
678or about 69 N 89 E, on the Putorana Plateau of Siberia.
679
680B<NOTE>: you B<cannot> get from A to B like this:
681
682   Dist = great_circle_distance(A, B)
683   Dir  = great_circle_direction(A, B)
684   C    = great_circle_destination(A, Dist, Dir)
685
686and expect C to be B, because the bearing constantly changes when
687going from A to B (except in some special case like the meridians or
688the circles of latitudes) and in great_circle_destination() one gives
689a B<constant> bearing to follow.
690
691=head2 CAVEAT FOR GREAT CIRCLE FORMULAS
692
693The answers may be off by few percentages because of the irregular
694(slightly aspherical) form of the Earth.  The errors are at worst
695about 0.55%, but generally below 0.3%.
696
697=head2 Real-valued asin and acos
698
699For small inputs asin() and acos() may return complex numbers even
700when real numbers would be enough and correct, this happens because of
701floating-point inaccuracies.  You can see these inaccuracies for
702example by trying theses:
703
704  print cos(1e-6)**2+sin(1e-6)**2 - 1,"\n";
705  printf "%.20f", cos(1e-6)**2+sin(1e-6)**2,"\n";
706
707which will print something like this
708
709  -1.11022302462516e-16
710  0.99999999999999988898
711
712even though the expected results are of course exactly zero and one.
713The formulas used to compute asin() and acos() are quite sensitive to
714this, and therefore they might accidentally slip into the complex
715plane even when they should not.  To counter this there are two
716interfaces that are guaranteed to return a real-valued output.
717
718=over 4
719
720=item asin_real
721
722    use Math::Trig qw(asin_real);
723
724    $real_angle = asin_real($input_sin);
725
726Return a real-valued arcus sine if the input is between [-1, 1],
727B<inclusive> the endpoints.  For inputs greater than one, pi/2
728is returned.  For inputs less than minus one, -pi/2 is returned.
729
730=item acos_real
731
732    use Math::Trig qw(acos_real);
733
734    $real_angle = acos_real($input_cos);
735
736Return a real-valued arcus cosine if the input is between [-1, 1],
737B<inclusive> the endpoints.  For inputs greater than one, zero
738is returned.  For inputs less than minus one, pi is returned.
739
740=back
741
742=head1 BUGS
743
744Saying C<use Math::Trig;> exports many mathematical routines in the
745caller environment and even overrides some (C<sin>, C<cos>).  This is
746construed as a feature by the Authors, actually... ;-)
747
748The code is not optimized for speed, especially because we use
749C<Math::Complex> and thus go quite near complex numbers while doing
750the computations even when the arguments are not. This, however,
751cannot be completely avoided if we want things like C<asin(2)> to give
752an answer instead of giving a fatal runtime error.
753
754Do not attempt navigation using these formulas.
755
756=head1 SEE ALSO
757
758L<Math::Complex>
759
760=head1 AUTHORS
761
762Jarkko Hietaniemi <F<jhi!at!iki.fi>>,
763Raphael Manfredi <F<Raphael_Manfredi!at!pobox.com>>,
764Zefram <zefram@fysh.org>
765
766=head1 LICENSE
767
768This library is free software; you can redistribute it and/or modify
769it under the same terms as Perl itself.
770
771=cut
772
773# eof
774