This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
$attributes::VERSION++ following change 33985.
[perl5.git] / lib / Math / Trig.pm
CommitLineData
5aabfad6 1#
2# Trigonometric functions, mostly inherited from Math::Complex.
d54bf66f 3# -- Jarkko Hietaniemi, since April 1997
5cd24f17 4# -- Raphael Manfredi, September 1996 (indirectly: because of Math::Complex)
5aabfad6 5#
6
7require Exporter;
8package Math::Trig;
9
affad850 10use 5.005;
5aabfad6 11use strict;
12
f1e71051 13use Math::Complex 1.54;
affad850 14use Math::Complex qw(:trig :pi);
5aabfad6 15
affad850 16use vars qw($VERSION $PACKAGE @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
5aabfad6 17
18@ISA = qw(Exporter);
19
f1e71051 20$VERSION = 1.18;
5aabfad6 21
ace5de91 22my @angcnv = qw(rad2deg rad2grad
d139edd6
JH
23 deg2rad deg2grad
24 grad2rad grad2deg);
5aabfad6 25
f3828575
SP
26my @areal = qw(asin_real acos_real);
27
5aabfad6 28@EXPORT = (@{$Math::Complex::EXPORT_TAGS{'trig'}},
f3828575 29 @angcnv, @areal);
5aabfad6 30
d54bf66f
JH
31my @rdlcnv = qw(cartesian_to_cylindrical
32 cartesian_to_spherical
33 cylindrical_to_cartesian
34 cylindrical_to_spherical
35 spherical_to_cartesian
36 spherical_to_cylindrical);
37
bf5f1b4c
JH
38my @greatcircle = qw(
39 great_circle_distance
40 great_circle_direction
41 great_circle_bearing
42 great_circle_waypoint
43 great_circle_midpoint
44 great_circle_destination
45 );
d54bf66f 46
affad850 47my @pi = qw(pi pi2 pi4 pip2 pip4);
bf5f1b4c 48
1515bec6 49@EXPORT_OK = (@rdlcnv, @greatcircle, @pi, 'Inf');
bf5f1b4c
JH
50
51# See e.g. the following pages:
52# http://www.movable-type.co.uk/scripts/LatLong.html
53# http://williams.best.vwh.net/avform.htm
54
55%EXPORT_TAGS = ('radial' => [ @rdlcnv ],
56 'great_circle' => [ @greatcircle ],
57 'pi' => [ @pi ]);
d54bf66f 58
affad850
SP
59sub _DR () { pi2/360 }
60sub _RD () { 360/pi2 }
61sub _DG () { 400/360 }
62sub _GD () { 360/400 }
63sub _RG () { 400/pi2 }
64sub _GR () { pi2/400 }
5aabfad6 65
66#
67# Truncating remainder.
68#
69
affad850 70sub _remt ($$) {
5aabfad6 71 # Oh yes, POSIX::fmod() would be faster. Possibly. If it is available.
72 $_[0] - $_[1] * int($_[0] / $_[1]);
73}
74
75#
76# Angle conversions.
77#
78
affad850 79sub rad2rad($) { _remt($_[0], pi2) }
9db5a202 80
affad850 81sub deg2deg($) { _remt($_[0], 360) }
9db5a202 82
affad850 83sub grad2grad($) { _remt($_[0], 400) }
5aabfad6 84
affad850 85sub rad2deg ($;$) { my $d = _RD * $_[0]; $_[1] ? $d : deg2deg($d) }
5aabfad6 86
affad850 87sub deg2rad ($;$) { my $d = _DR * $_[0]; $_[1] ? $d : rad2rad($d) }
5aabfad6 88
affad850 89sub grad2deg ($;$) { my $d = _GD * $_[0]; $_[1] ? $d : deg2deg($d) }
5aabfad6 90
affad850 91sub deg2grad ($;$) { my $d = _DG * $_[0]; $_[1] ? $d : grad2grad($d) }
5aabfad6 92
affad850 93sub rad2grad ($;$) { my $d = _RG * $_[0]; $_[1] ? $d : grad2grad($d) }
9db5a202 94
affad850 95sub grad2rad ($;$) { my $d = _GR * $_[0]; $_[1] ? $d : rad2rad($d) }
5aabfad6 96
f3828575
SP
97#
98# acos and asin functions which always return a real number
99#
100
101sub acos_real {
102 return 0 if $_[0] >= 1;
103 return pi if $_[0] <= -1;
104 return acos($_[0]);
105}
106
107sub asin_real {
108 return &pip2 if $_[0] >= 1;
109 return -&pip2 if $_[0] <= -1;
110 return asin($_[0]);
111}
112
d54bf66f
JH
113sub cartesian_to_spherical {
114 my ( $x, $y, $z ) = @_;
115
116 my $rho = sqrt( $x * $x + $y * $y + $z * $z );
117
118 return ( $rho,
119 atan2( $y, $x ),
f3828575 120 $rho ? acos_real( $z / $rho ) : 0 );
d54bf66f
JH
121}
122
123sub spherical_to_cartesian {
124 my ( $rho, $theta, $phi ) = @_;
125
126 return ( $rho * cos( $theta ) * sin( $phi ),
127 $rho * sin( $theta ) * sin( $phi ),
128 $rho * cos( $phi ) );
129}
130
131sub spherical_to_cylindrical {
132 my ( $x, $y, $z ) = spherical_to_cartesian( @_ );
133
134 return ( sqrt( $x * $x + $y * $y ), $_[1], $z );
135}
136
137sub cartesian_to_cylindrical {
138 my ( $x, $y, $z ) = @_;
139
140 return ( sqrt( $x * $x + $y * $y ), atan2( $y, $x ), $z );
141}
142
143sub cylindrical_to_cartesian {
144 my ( $rho, $theta, $z ) = @_;
145
146 return ( $rho * cos( $theta ), $rho * sin( $theta ), $z );
147}
148
149sub cylindrical_to_spherical {
150 return ( cartesian_to_spherical( cylindrical_to_cartesian( @_ ) ) );
151}
152
153sub great_circle_distance {
154 my ( $theta0, $phi0, $theta1, $phi1, $rho ) = @_;
155
156 $rho = 1 unless defined $rho; # Default to the unit sphere.
157
158 my $lat0 = pip2 - $phi0;
159 my $lat1 = pip2 - $phi1;
160
161 return $rho *
f3828575
SP
162 acos_real( cos( $lat0 ) * cos( $lat1 ) * cos( $theta0 - $theta1 ) +
163 sin( $lat0 ) * sin( $lat1 ) );
d54bf66f
JH
164}
165
7e5f197a
JH
166sub great_circle_direction {
167 my ( $theta0, $phi0, $theta1, $phi1 ) = @_;
168
d139edd6
JH
169 my $distance = &great_circle_distance;
170
7e5f197a
JH
171 my $lat0 = pip2 - $phi0;
172 my $lat1 = pip2 - $phi1;
173
174 my $direction =
f3828575
SP
175 acos_real((sin($lat1) - sin($lat0) * cos($distance)) /
176 (cos($lat0) * sin($distance)));
177
d139edd6
JH
178 $direction = pi2 - $direction
179 if sin($theta1 - $theta0) < 0;
7e5f197a
JH
180
181 return rad2rad($direction);
182}
183
f1e71051 184*great_circle_bearing = \&great_circle_direction;
bf5f1b4c
JH
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);
f3828575 210 my $phi = acos_real($z);
f1e71051 211
bf5f1b4c
JH
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
f1e71051 224 my $phi1 = asin_real(sin($lat0)*cos($dst) +
f3828575 225 cos($lat0)*sin($dst)*cos($dir0));
f1e71051 226
bf5f1b4c
JH
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
ea0630ea
HS
2371;
238
239__END__
d54bf66f
JH
240=pod
241
5aabfad6 242=head1 NAME
243
244Math::Trig - trigonometric functions
245
246=head1 SYNOPSIS
247
affad850 248 use Math::Trig;
3cb6de81 249
affad850
SP
250 $x = tan(0.9);
251 $y = acos(3.7);
252 $z = asin(2.4);
3cb6de81 253
affad850 254 $halfpi = pi/2;
5aabfad6 255
affad850 256 $rad = deg2rad(120);
5aabfad6 257
affad850
SP
258 # Import constants pi2, pip2, pip4 (2*pi, pi/2, pi/4).
259 use Math::Trig ':pi';
bf5f1b4c 260
affad850
SP
261 # Import the conversions between cartesian/spherical/cylindrical.
262 use Math::Trig ':radial';
bf5f1b4c
JH
263
264 # Import the great circle formulas.
affad850 265 use Math::Trig ':great_circle';
bf5f1b4c 266
5aabfad6 267=head1 DESCRIPTION
268
269C<Math::Trig> defines many trigonometric functions not defined by the
4ae80833 270core Perl which defines only the C<sin()> and C<cos()>. The constant
5aabfad6 271B<pi> is also defined as are a few convenience functions for angle
bf5f1b4c 272conversions, and I<great circle formulas> for spherical movement.
5aabfad6 273
274=head1 TRIGONOMETRIC FUNCTIONS
275
276The tangent
277
d54bf66f
JH
278=over 4
279
280=item B<tan>
281
282=back
5aabfad6 283
284The cofunctions of the sine, cosine, and tangent (cosec/csc and cotan/cot
285are aliases)
286
d54bf66f 287B<csc>, B<cosec>, B<sec>, B<sec>, B<cot>, B<cotan>
5aabfad6 288
289The arcus (also known as the inverse) functions of the sine, cosine,
290and tangent
291
d54bf66f 292B<asin>, B<acos>, B<atan>
5aabfad6 293
294The principal value of the arc tangent of y/x
295
d54bf66f 296B<atan2>(y, x)
5aabfad6 297
298The arcus cofunctions of the sine, cosine, and tangent (acosec/acsc
affad850 299and acotan/acot are aliases). Note that atan2(0, 0) is not well-defined.
5aabfad6 300
d54bf66f 301B<acsc>, B<acosec>, B<asec>, B<acot>, B<acotan>
5aabfad6 302
303The hyperbolic sine, cosine, and tangent
304
d54bf66f 305B<sinh>, B<cosh>, B<tanh>
5aabfad6 306
307The cofunctions of the hyperbolic sine, cosine, and tangent (cosech/csch
308and cotanh/coth are aliases)
309
d54bf66f 310B<csch>, B<cosech>, B<sech>, B<coth>, B<cotanh>
5aabfad6 311
f1e71051 312The area (also known as the inverse) functions of the hyperbolic
5aabfad6 313sine, cosine, and tangent
314
d54bf66f 315B<asinh>, B<acosh>, B<atanh>
5aabfad6 316
f1e71051 317The area cofunctions of the hyperbolic sine, cosine, and tangent
5aabfad6 318(acsch/acosech and acoth/acotanh are aliases)
319
d54bf66f 320B<acsch>, B<acosech>, B<asech>, B<acoth>, B<acotanh>
5aabfad6 321
affad850
SP
322The trigonometric constant B<pi> and some of handy multiples
323of it are also defined.
5aabfad6 324
affad850 325B<pi, pi2, pi4, pip2, pip4>
5aabfad6 326
5cd24f17 327=head2 ERRORS DUE TO DIVISION BY ZERO
328
329The following functions
330
affad850
SP
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
5cd24f17 345
346cannot be computed for all arguments because that would mean dividing
8c03c583
JH
347by zero or taking logarithm of zero. These situations cause fatal
348runtime errors looking like this
5cd24f17 349
affad850
SP
350 cot(0): Division by zero.
351 (Because in the definition of cot(0), the divisor sin(0) is 0)
352 Died at ...
5cd24f17 353
8c03c583
JH
354or
355
affad850
SP
356 atanh(-1): Logarithm of zero.
357 Died at...
8c03c583
JH
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 *
affad850
SP
364pi>, where I<k> is any integer.
365
366Note that atan2(0, 0) is not well-defined.
5cd24f17 367
368=head2 SIMPLE (REAL) ARGUMENTS, COMPLEX RESULTS
5aabfad6 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
affad850 386 print asin(2), "\n";
3cb6de81 387
5aabfad6 388should produce something like this (take or leave few last decimals):
389
affad850 390 1.5707963267949-1.31695789692482i
5aabfad6 391
5cd24f17 392That is, a complex number with the real part of approximately C<1.571>
393and the imaginary part of approximately C<-1.317>.
5aabfad6 394
d54bf66f 395=head1 PLANE ANGLE CONVERSIONS
5aabfad6 396
397(Plane, 2-dimensional) angles may be converted with the following functions.
398
affad850
SP
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);
3cb6de81 412
affad850 413=item grad2deg
3cb6de81 414
affad850
SP
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
5aabfad6 426
5cd24f17 427The full circle is 2 I<pi> radians or I<360> degrees or I<400> gradians.
9db5a202
JH
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
affad850
SP
431 $zillions_of_radians = deg2rad($zillions_of_degrees, 1);
432 $negative_degrees = rad2deg($negative_radians, 1);
9db5a202
JH
433
434You can also do the wrapping explicitly by rad2rad(), deg2deg(), and
435grad2grad().
5aabfad6 436
affad850
SP
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
d54bf66f
JH
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
bf5f1b4c 474B<Cartesian> coordinates are the usual rectangular I<(x, y, z)>-coordinates.
d54bf66f
JH
475
476Spherical coordinates, I<(rho, theta, pi)>, 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
2d6f5264
JH
482I<polar> coordinate. The North Pole is therefore I<0, 0, rho>, and
483the Gulf of Guinea (think of the missing big chunk of Africa) I<0,
4b0d1da8
JH
484pi/2, rho>. In geographical terms I<phi> is latitude (northward
485positive, southward negative) and I<theta> is longitude (eastward
486positive, westward negative).
d54bf66f 487
4b0d1da8 488B<BEWARE>: some texts define I<theta> and I<phi> the other way round,
d54bf66f
JH
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
affad850 511 ($rho, $theta, $z) = cartesian_to_cylindrical($x, $y, $z);
d54bf66f
JH
512
513=item cartesian_to_spherical
514
affad850 515 ($rho, $theta, $phi) = cartesian_to_spherical($x, $y, $z);
d54bf66f
JH
516
517=item cylindrical_to_cartesian
518
affad850 519 ($x, $y, $z) = cylindrical_to_cartesian($rho, $theta, $z);
d54bf66f
JH
520
521=item cylindrical_to_spherical
522
affad850 523 ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);
d54bf66f
JH
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
affad850 529 ($x, $y, $z) = spherical_to_cartesian($rho, $theta, $phi);
d54bf66f
JH
530
531=item spherical_to_cylindrical
532
affad850 533 ($rho_c, $theta, $z) = spherical_to_cylindrical($rho_s, $theta, $phi);
d54bf66f
JH
534
535Notice that when C<$z> is not 0 C<$rho_c> is not equal to C<$rho_s>.
536
537=back
538
7e5f197a 539=head1 GREAT CIRCLE DISTANCES AND DIRECTIONS
d54bf66f 540
affad850
SP
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
d54bf66f 548You can compute spherical distances, called B<great circle distances>,
7e5f197a 549by importing the great_circle_distance() function:
d54bf66f 550
7e5f197a 551 use Math::Trig 'great_circle_distance';
d54bf66f 552
4b0d1da8 553 $distance = great_circle_distance($theta0, $phi0, $theta1, $phi1, [, $rho]);
d54bf66f
JH
554
555The I<great circle distance> is the shortest distance between two
556points on a sphere. The distance is in C<$rho> units. The C<$rho> is
557optional, it defaults to 1 (the unit sphere), therefore the distance
558defaults to radians.
559
4b0d1da8 560If you think geographically the I<theta> are longitudes: zero at the
f3828575 561Greenwhich meridian, eastward positive, westward negative -- and the
2d06e7d7 562I<phi> are latitudes: zero at the North Pole, northward positive,
4b0d1da8 563southward negative. B<NOTE>: this formula thinks in mathematics, not
2d06e7d7
JH
564geographically: the I<phi> zero is at the North Pole, not at the
565Equator on the west coast of Africa (Bay of Guinea). You need to
566subtract your geographical coordinates from I<pi/2> (also known as 90
567degrees).
4b0d1da8
JH
568
569 $distance = great_circle_distance($lon0, pi/2 - $lat0,
570 $lon1, pi/2 - $lat1, $rho);
571
affad850
SP
572=head2 great_circle_direction
573
bf5f1b4c
JH
574The direction you must follow the great circle (also known as I<bearing>)
575can be computed by the great_circle_direction() function:
7e5f197a
JH
576
577 use Math::Trig 'great_circle_direction';
578
579 $direction = great_circle_direction($theta0, $phi0, $theta1, $phi1);
580
affad850
SP
581=head2 great_circle_bearing
582
583Alias 'great_circle_bearing' for 'great_circle_direction' is also available.
584
585 use Math::Trig 'great_circle_bearing';
586
587 $direction = great_circle_bearing($theta0, $phi0, $theta1, $phi1);
588
589The result of great_circle_direction is in radians, zero indicating
590straight north, pi or -pi straight south, pi/2 straight west, and
591-pi/2 straight east.
7e5f197a 592
f1e71051
RGS
593=head2 great_circle_destination
594
bf5f1b4c
JH
595You can inversely compute the destination if you know the
596starting point, direction, and distance:
597
598 use Math::Trig 'great_circle_destination';
599
f1e71051
RGS
600 # $diro is the original direction,
601 # for example from great_circle_bearing().
602 # $distance is the angular distance in radians,
603 # for example from great_circle_distance().
604 # $thetad and $phid are the destination coordinates,
605 # $dird is the final direction at the destination.
bf5f1b4c
JH
606
607 ($thetad, $phid, $dird) =
f1e71051 608 great_circle_destination($theta, $phi, $diro, $distance);
bf5f1b4c
JH
609
610or the midpoint if you know the end points:
611
affad850
SP
612=head2 great_circle_midpoint
613
bf5f1b4c
JH
614 use Math::Trig 'great_circle_midpoint';
615
616 ($thetam, $phim) =
617 great_circle_midpoint($theta0, $phi0, $theta1, $phi1);
618
619The great_circle_midpoint() is just a special case of
620
affad850
SP
621=head2 great_circle_waypoint
622
bf5f1b4c
JH
623 use Math::Trig 'great_circle_waypoint';
624
625 ($thetai, $phii) =
626 great_circle_waypoint($theta0, $phi0, $theta1, $phi1, $way);
627
628Where the $way is a value from zero ($theta0, $phi0) to one ($theta1,
629$phi1). Note that antipodal points (where their distance is I<pi>
630radians) do not have waypoints between them (they would have an an
631"equator" between them), and therefore C<undef> is returned for
632antipodal points. If the points are the same and the distance
633therefore zero and all waypoints therefore identical, the first point
634(either point) is returned.
635
636The thetas, phis, direction, and distance in the above are all in radians.
637
638You can import all the great circle formulas by
639
640 use Math::Trig ':great_circle';
641
7e5f197a
JH
642Notice that the resulting directions might be somewhat surprising if
643you are looking at a flat worldmap: in such map projections the great
f3828575 644circles quite often do not look like the shortest routes -- but for
7e5f197a 645example the shortest possible routes from Europe or North America to
f3828575
SP
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.)
7e5f197a 649
51301382 650=head1 EXAMPLES
d54bf66f 651
7e5f197a
JH
652To calculate the distance between London (51.3N 0.5W) and Tokyo
653(35.7N 139.8E) in kilometers:
d54bf66f 654
affad850 655 use Math::Trig qw(great_circle_distance deg2rad);
d54bf66f 656
affad850
SP
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.
d54bf66f 662
bf5f1b4c
JH
663The direction you would have to go from London to Tokyo (in radians,
664straight north being zero, straight east being pi/2).
7e5f197a 665
affad850 666 use Math::Trig qw(great_circle_direction);
7e5f197a 667
affad850 668 my $rad = great_circle_direction(@L, @T); # About 0.547 or 0.174 pi.
7e5f197a 669
bf5f1b4c 670The midpoint between London and Tokyo being
7e5f197a 671
affad850 672 use Math::Trig qw(great_circle_midpoint);
bf5f1b4c 673
affad850 674 my @M = great_circle_midpoint(@L, @T);
bf5f1b4c 675
f1e71051
RGS
676or about 69 N 89 E, in the frozen wastes of Siberia.
677
678B<NOTE>: you B<cannot> get from A to B like this:
679
680 Dist = great_circle_distance(A, B)
681 Dir = great_circle_direction(A, B)
682 C = great_circle_destination(A, Dist, Dir)
683
684and expect C to be B, because the bearing constantly changes when
685going from A to B (except in some special case like the meridians or
686the circles of latitudes) and in great_circle_destination() one gives
687a constant bearing to follow.
41bd693c 688
bf5f1b4c 689=head2 CAVEAT FOR GREAT CIRCLE FORMULAS
41bd693c 690
bf5f1b4c
JH
691The answers may be off by few percentages because of the irregular
692(slightly aspherical) form of the Earth. The errors are at worst
693about 0.55%, but generally below 0.3%.
d54bf66f 694
f3828575
SP
695=head2 Real-valued asin and acos
696
697For small inputs asin() and acos() may return complex numbers even
698when real numbers would be enough and correct, this happens because of
699floating-point inaccuracies. You can see these inaccuracies for
700example by trying theses:
701
702 print cos(1e-6)**2+sin(1e-6)**2 - 1,"\n";
703 printf "%.20f", cos(1e-6)**2+sin(1e-6)**2,"\n";
704
705which will print something like this
706
707 -1.11022302462516e-16
708 0.99999999999999988898
709
710even though the expected results are of course exactly zero and one.
711The formulas used to compute asin() and acos() are quite sensitive to
712this, and therefore they might accidentally slip into the complex
713plane even when they should not. To counter this there are two
714interfaces that are guaranteed to return a real-valued output.
715
716=over 4
717
718=item asin_real
719
720 use Math::Trig qw(asin_real);
721
722 $real_angle = asin_real($input_sin);
723
724Return a real-valued arcus sine if the input is between [-1, 1],
725B<inclusive> the endpoints. For inputs greater than one, pi/2
726is returned. For inputs less than minus one, -pi/2 is returned.
727
728=item acos_real
729
730 use Math::Trig qw(acos_real);
731
732 $real_angle = acos_real($input_cos);
733
734Return a real-valued arcus cosine if the input is between [-1, 1],
735B<inclusive> the endpoints. For inputs greater than one, zero
736is returned. For inputs less than minus one, pi is returned.
737
738=back
739
5cd24f17 740=head1 BUGS
5aabfad6 741
5cd24f17 742Saying C<use Math::Trig;> exports many mathematical routines in the
743caller environment and even overrides some (C<sin>, C<cos>). This is
744construed as a feature by the Authors, actually... ;-)
5aabfad6 745
5cd24f17 746The code is not optimized for speed, especially because we use
747C<Math::Complex> and thus go quite near complex numbers while doing
748the computations even when the arguments are not. This, however,
749cannot be completely avoided if we want things like C<asin(2)> to give
750an answer instead of giving a fatal runtime error.
5aabfad6 751
bf5f1b4c
JH
752Do not attempt navigation using these formulas.
753
7637cd07
SP
754L<Math::Complex>
755
5cd24f17 756=head1 AUTHORS
5aabfad6 757
affad850
SP
758Jarkko Hietaniemi <F<jhi!at!iki.fi>> and
759Raphael Manfredi <F<Raphael_Manfredi!at!pobox.com>>.
5aabfad6 760
1515bec6
SP
761=head1 LICENSE
762
763This library is free software; you can redistribute it and/or modify
764it under the same terms as Perl itself.
765
5aabfad6 766=cut
767
768# eof