Term::Complete problem + fix (Was: Re: muttprofile + perl 5.8)
[p5sagit/p5-mst-13.2.git] / lib / Math / Trig.pm
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
7 require Exporter;
8 package Math::Trig;
9
10 use 5.006;
11 use strict;
12
13 use Math::Complex qw(:trig);
14
15 our($VERSION, $PACKAGE, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
16
17 @ISA = qw(Exporter);
18
19 $VERSION = 1.02;
20
21 my @angcnv = qw(rad2deg rad2grad
22              deg2rad deg2grad
23              grad2rad grad2deg);
24
25 @EXPORT = (@{$Math::Complex::EXPORT_TAGS{'trig'}},
26            @angcnv);
27
28 my @rdlcnv = qw(cartesian_to_cylindrical
29                 cartesian_to_spherical
30                 cylindrical_to_cartesian
31                 cylindrical_to_spherical
32                 spherical_to_cartesian
33                 spherical_to_cylindrical);
34
35 @EXPORT_OK = (@rdlcnv, 'great_circle_distance', 'great_circle_direction');
36
37 %EXPORT_TAGS = ('radial' => [ @rdlcnv ]);
38
39 sub pi2  () { 2 * pi }
40 sub pip2 () { pi / 2 }
41
42 sub DR  () { pi2/360 }
43 sub RD  () { 360/pi2 }
44 sub DG  () { 400/360 }
45 sub GD  () { 360/400 }
46 sub RG  () { 400/pi2 }
47 sub GR  () { pi2/400 }
48
49 #
50 # Truncating remainder.
51 #
52
53 sub remt ($$) {
54     # Oh yes, POSIX::fmod() would be faster. Possibly. If it is available.
55     $_[0] - $_[1] * int($_[0] / $_[1]);
56 }
57
58 #
59 # Angle conversions.
60 #
61
62 sub rad2rad($)     { remt($_[0], pi2) }
63
64 sub deg2deg($)     { remt($_[0], 360) }
65
66 sub grad2grad($)   { remt($_[0], 400) }
67
68 sub rad2deg ($;$)  { my $d = RD * $_[0]; $_[1] ? $d : deg2deg($d) }
69
70 sub deg2rad ($;$)  { my $d = DR * $_[0]; $_[1] ? $d : rad2rad($d) }
71
72 sub grad2deg ($;$) { my $d = GD * $_[0]; $_[1] ? $d : deg2deg($d) }
73
74 sub deg2grad ($;$) { my $d = DG * $_[0]; $_[1] ? $d : grad2grad($d) }
75
76 sub rad2grad ($;$) { my $d = RG * $_[0]; $_[1] ? $d : grad2grad($d) }
77
78 sub grad2rad ($;$) { my $d = GR * $_[0]; $_[1] ? $d : rad2rad($d) }
79
80 sub cartesian_to_spherical {
81     my ( $x, $y, $z ) = @_;
82
83     my $rho = sqrt( $x * $x + $y * $y + $z * $z );
84
85     return ( $rho,
86              atan2( $y, $x ),
87              $rho ? acos( $z / $rho ) : 0 );
88 }
89
90 sub spherical_to_cartesian {
91     my ( $rho, $theta, $phi ) = @_;
92
93     return ( $rho * cos( $theta ) * sin( $phi ),
94              $rho * sin( $theta ) * sin( $phi ),
95              $rho * cos( $phi   ) );
96 }
97
98 sub spherical_to_cylindrical {
99     my ( $x, $y, $z ) = spherical_to_cartesian( @_ );
100
101     return ( sqrt( $x * $x + $y * $y ), $_[1], $z );
102 }
103
104 sub cartesian_to_cylindrical {
105     my ( $x, $y, $z ) = @_;
106
107     return ( sqrt( $x * $x + $y * $y ), atan2( $y, $x ), $z );
108 }
109
110 sub cylindrical_to_cartesian {
111     my ( $rho, $theta, $z ) = @_;
112
113     return ( $rho * cos( $theta ), $rho * sin( $theta ), $z );
114 }
115
116 sub cylindrical_to_spherical {
117     return ( cartesian_to_spherical( cylindrical_to_cartesian( @_ ) ) );
118 }
119
120 sub great_circle_distance {
121     my ( $theta0, $phi0, $theta1, $phi1, $rho ) = @_;
122
123     $rho = 1 unless defined $rho; # Default to the unit sphere.
124
125     my $lat0 = pip2 - $phi0;
126     my $lat1 = pip2 - $phi1;
127
128     return $rho *
129         acos(cos( $lat0 ) * cos( $lat1 ) * cos( $theta0 - $theta1 ) +
130              sin( $lat0 ) * sin( $lat1 ) );
131 }
132
133 sub great_circle_direction {
134     my ( $theta0, $phi0, $theta1, $phi1 ) = @_;
135
136     my $lat0 = pip2 - $phi0;
137     my $lat1 = pip2 - $phi1;
138
139     my $direction =
140         atan2(sin($theta0 - $theta1) * cos($lat1),
141               cos($lat0) * sin($lat1) -
142               sin($lat0) * cos($lat1) * cos($theta0 - $theta1));
143
144     return rad2rad($direction);
145 }
146
147 1;
148
149 __END__
150 =pod
151
152 =head1 NAME
153
154 Math::Trig - trigonometric functions
155
156 =head1 SYNOPSIS
157
158         use Math::Trig;
159
160         $x = tan(0.9);
161         $y = acos(3.7);
162         $z = asin(2.4);
163
164         $halfpi = pi/2;
165
166         $rad = deg2rad(120);
167
168 =head1 DESCRIPTION
169
170 C<Math::Trig> defines many trigonometric functions not defined by the
171 core Perl which defines only the C<sin()> and C<cos()>.  The constant
172 B<pi> is also defined as are a few convenience functions for angle
173 conversions.
174
175 =head1 TRIGONOMETRIC FUNCTIONS
176
177 The tangent
178
179 =over 4
180
181 =item B<tan>
182
183 =back
184
185 The cofunctions of the sine, cosine, and tangent (cosec/csc and cotan/cot
186 are aliases)
187
188 B<csc>, B<cosec>, B<sec>, B<sec>, B<cot>, B<cotan>
189
190 The arcus (also known as the inverse) functions of the sine, cosine,
191 and tangent
192
193 B<asin>, B<acos>, B<atan>
194
195 The principal value of the arc tangent of y/x
196
197 B<atan2>(y, x)
198
199 The arcus cofunctions of the sine, cosine, and tangent (acosec/acsc
200 and acotan/acot are aliases)
201
202 B<acsc>, B<acosec>, B<asec>, B<acot>, B<acotan>
203
204 The hyperbolic sine, cosine, and tangent
205
206 B<sinh>, B<cosh>, B<tanh>
207
208 The cofunctions of the hyperbolic sine, cosine, and tangent (cosech/csch
209 and cotanh/coth are aliases)
210
211 B<csch>, B<cosech>, B<sech>, B<coth>, B<cotanh>
212
213 The arcus (also known as the inverse) functions of the hyperbolic
214 sine, cosine, and tangent
215
216 B<asinh>, B<acosh>, B<atanh>
217
218 The arcus cofunctions of the hyperbolic sine, cosine, and tangent
219 (acsch/acosech and acoth/acotanh are aliases)
220
221 B<acsch>, B<acosech>, B<asech>, B<acoth>, B<acotanh>
222
223 The trigonometric constant B<pi> is also defined.
224
225 $pi2 = 2 * B<pi>;
226
227 =head2 ERRORS DUE TO DIVISION BY ZERO
228
229 The following functions
230
231         acoth
232         acsc
233         acsch
234         asec
235         asech
236         atanh
237         cot
238         coth
239         csc
240         csch
241         sec
242         sech
243         tan
244         tanh
245
246 cannot be computed for all arguments because that would mean dividing
247 by zero or taking logarithm of zero. These situations cause fatal
248 runtime errors looking like this
249
250         cot(0): Division by zero.
251         (Because in the definition of cot(0), the divisor sin(0) is 0)
252         Died at ...
253
254 or
255
256         atanh(-1): Logarithm of zero.
257         Died at...
258
259 For the C<csc>, C<cot>, C<asec>, C<acsc>, C<acot>, C<csch>, C<coth>,
260 C<asech>, C<acsch>, the argument cannot be C<0> (zero).  For the
261 C<atanh>, C<acoth>, the argument cannot be C<1> (one).  For the
262 C<atanh>, C<acoth>, the argument cannot be C<-1> (minus one).  For the
263 C<tan>, C<sec>, C<tanh>, C<sech>, the argument cannot be I<pi/2 + k *
264 pi>, where I<k> is any integer.
265
266 =head2 SIMPLE (REAL) ARGUMENTS, COMPLEX RESULTS
267
268 Please note that some of the trigonometric functions can break out
269 from the B<real axis> into the B<complex plane>. For example
270 C<asin(2)> has no definition for plain real numbers but it has
271 definition for complex numbers.
272
273 In Perl terms this means that supplying the usual Perl numbers (also
274 known as scalars, please see L<perldata>) as input for the
275 trigonometric functions might produce as output results that no more
276 are simple real numbers: instead they are complex numbers.
277
278 The C<Math::Trig> handles this by using the C<Math::Complex> package
279 which knows how to handle complex numbers, please see L<Math::Complex>
280 for more information. In practice you need not to worry about getting
281 complex numbers as results because the C<Math::Complex> takes care of
282 details like for example how to display complex numbers. For example:
283
284         print asin(2), "\n";
285
286 should produce something like this (take or leave few last decimals):
287
288         1.5707963267949-1.31695789692482i
289
290 That is, a complex number with the real part of approximately C<1.571>
291 and the imaginary part of approximately C<-1.317>.
292
293 =head1 PLANE ANGLE CONVERSIONS
294
295 (Plane, 2-dimensional) angles may be converted with the following functions.
296
297         $radians  = deg2rad($degrees);
298         $radians  = grad2rad($gradians);
299
300         $degrees  = rad2deg($radians);
301         $degrees  = grad2deg($gradians);
302
303         $gradians = deg2grad($degrees);
304         $gradians = rad2grad($radians);
305
306 The full circle is 2 I<pi> radians or I<360> degrees or I<400> gradians.
307 The result is by default wrapped to be inside the [0, {2pi,360,400}[ circle.
308 If you don't want this, supply a true second argument:
309
310         $zillions_of_radians  = deg2rad($zillions_of_degrees, 1);
311         $negative_degrees     = rad2deg($negative_radians, 1);
312
313 You can also do the wrapping explicitly by rad2rad(), deg2deg(), and
314 grad2grad().
315
316 =head1 RADIAL COORDINATE CONVERSIONS
317
318 B<Radial coordinate systems> are the B<spherical> and the B<cylindrical>
319 systems, explained shortly in more detail.
320
321 You can import radial coordinate conversion functions by using the
322 C<:radial> tag:
323
324     use Math::Trig ':radial';
325
326     ($rho, $theta, $z)     = cartesian_to_cylindrical($x, $y, $z);
327     ($rho, $theta, $phi)   = cartesian_to_spherical($x, $y, $z);
328     ($x, $y, $z)           = cylindrical_to_cartesian($rho, $theta, $z);
329     ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);
330     ($x, $y, $z)           = spherical_to_cartesian($rho, $theta, $phi);
331     ($rho_c, $theta, $z)   = spherical_to_cylindrical($rho_s, $theta, $phi);
332
333 B<All angles are in radians>.
334
335 =head2 COORDINATE SYSTEMS
336
337 B<Cartesian> coordinates are the usual rectangular I<(x, y,
338 z)>-coordinates.
339
340 Spherical coordinates, I<(rho, theta, pi)>, are three-dimensional
341 coordinates which define a point in three-dimensional space.  They are
342 based on a sphere surface.  The radius of the sphere is B<rho>, also
343 known as the I<radial> coordinate.  The angle in the I<xy>-plane
344 (around the I<z>-axis) is B<theta>, also known as the I<azimuthal>
345 coordinate.  The angle from the I<z>-axis is B<phi>, also known as the
346 I<polar> coordinate.  The `North Pole' is therefore I<0, 0, rho>, and
347 the `Bay of Guinea' (think of the missing big chunk of Africa) I<0,
348 pi/2, rho>.  In geographical terms I<phi> is latitude (northward
349 positive, southward negative) and I<theta> is longitude (eastward
350 positive, westward negative).
351
352 B<BEWARE>: some texts define I<theta> and I<phi> the other way round,
353 some texts define the I<phi> to start from the horizontal plane, some
354 texts use I<r> in place of I<rho>.
355
356 Cylindrical coordinates, I<(rho, theta, z)>, are three-dimensional
357 coordinates which define a point in three-dimensional space.  They are
358 based on a cylinder surface.  The radius of the cylinder is B<rho>,
359 also known as the I<radial> coordinate.  The angle in the I<xy>-plane
360 (around the I<z>-axis) is B<theta>, also known as the I<azimuthal>
361 coordinate.  The third coordinate is the I<z>, pointing up from the
362 B<theta>-plane.
363
364 =head2 3-D ANGLE CONVERSIONS
365
366 Conversions to and from spherical and cylindrical coordinates are
367 available.  Please notice that the conversions are not necessarily
368 reversible because of the equalities like I<pi> angles being equal to
369 I<-pi> angles.
370
371 =over 4
372
373 =item cartesian_to_cylindrical
374
375         ($rho, $theta, $z) = cartesian_to_cylindrical($x, $y, $z);
376
377 =item cartesian_to_spherical
378
379         ($rho, $theta, $phi) = cartesian_to_spherical($x, $y, $z);
380
381 =item cylindrical_to_cartesian
382
383         ($x, $y, $z) = cylindrical_to_cartesian($rho, $theta, $z);
384
385 =item cylindrical_to_spherical
386
387         ($rho_s, $theta, $phi) = cylindrical_to_spherical($rho_c, $theta, $z);
388
389 Notice that when C<$z> is not 0 C<$rho_s> is not equal to C<$rho_c>.
390
391 =item spherical_to_cartesian
392
393         ($x, $y, $z) = spherical_to_cartesian($rho, $theta, $phi);
394
395 =item spherical_to_cylindrical
396
397         ($rho_c, $theta, $z) = spherical_to_cylindrical($rho_s, $theta, $phi);
398
399 Notice that when C<$z> is not 0 C<$rho_c> is not equal to C<$rho_s>.
400
401 =back
402
403 =head1 GREAT CIRCLE DISTANCES AND DIRECTIONS
404
405 You can compute spherical distances, called B<great circle distances>,
406 by importing the great_circle_distance() function:
407
408   use Math::Trig 'great_circle_distance';
409
410   $distance = great_circle_distance($theta0, $phi0, $theta1, $phi1, [, $rho]);
411
412 The I<great circle distance> is the shortest distance between two
413 points on a sphere.  The distance is in C<$rho> units.  The C<$rho> is
414 optional, it defaults to 1 (the unit sphere), therefore the distance
415 defaults to radians.
416
417 If you think geographically the I<theta> are longitudes: zero at the
418 Greenwhich meridian, eastward positive, westward negative--and the
419 I<phi> are latitudes: zero at the North Pole, northward positive,
420 southward negative.  B<NOTE>: this formula thinks in mathematics, not
421 geographically: the I<phi> zero is at the North Pole, not at the
422 Equator on the west coast of Africa (Bay of Guinea).  You need to
423 subtract your geographical coordinates from I<pi/2> (also known as 90
424 degrees).
425
426   $distance = great_circle_distance($lon0, pi/2 - $lat0,
427                                     $lon1, pi/2 - $lat1, $rho);
428
429 The direction you must follow the great circle can be computed by the
430 great_circle_direction() function:
431
432   use Math::Trig 'great_circle_direction';
433
434   $direction = great_circle_direction($theta0, $phi0, $theta1, $phi1);
435
436 The result is in radians, zero indicating straight north, pi or -pi
437 straight south, pi/2 straight west, and -pi/2 straight east.
438
439 Notice that the resulting directions might be somewhat surprising if
440 you are looking at a flat worldmap: in such map projections the great
441 circles quite often do not look like the shortest routes-- but for
442 example the shortest possible routes from Europe or North America to
443 Asia do often cross the polar regions.
444
445 =head1 EXAMPLES
446
447 To calculate the distance between London (51.3N 0.5W) and Tokyo
448 (35.7N 139.8E) in kilometers:
449
450         use Math::Trig qw(great_circle_distance deg2rad);
451
452         # Notice the 90 - latitude: phi zero is at the North Pole.
453         @L = (deg2rad(-0.5), deg2rad(90 - 51.3));
454         @T = (deg2rad(139.8),deg2rad(90 - 35.7));
455
456         $km = great_circle_distance(@L, @T, 6378);
457
458 The direction you would have to go from London to Tokyo
459
460         use Math::Trig qw(great_circle_direction);
461
462         $rad = great_circle_direction(@L, @T);
463
464 =head2 CAVEAT FOR GREAT CIRCLE FORMULAS
465
466 The answers may be off by few percentages because of the irregular
467 (slightly aspherical) form of the Earth.  The formula used for
468 grear circle distances
469
470         lat0 = 90 degrees - phi0
471         lat1 = 90 degrees - phi1
472         d = R * arccos(cos(lat0) * cos(lat1) * cos(lon1 - lon01) +
473                        sin(lat0) * sin(lat1))
474
475 is also somewhat unreliable for small distances (for locations
476 separated less than about five degrees) because it uses arc cosine
477 which is rather ill-conditioned for values close to zero.
478
479 =head1 BUGS
480
481 Saying C<use Math::Trig;> exports many mathematical routines in the
482 caller environment and even overrides some (C<sin>, C<cos>).  This is
483 construed as a feature by the Authors, actually... ;-)
484
485 The code is not optimized for speed, especially because we use
486 C<Math::Complex> and thus go quite near complex numbers while doing
487 the computations even when the arguments are not. This, however,
488 cannot be completely avoided if we want things like C<asin(2)> to give
489 an answer instead of giving a fatal runtime error.
490
491 =head1 AUTHORS
492
493 Jarkko Hietaniemi <F<jhi@iki.fi>> and 
494 Raphael Manfredi <F<Raphael_Manfredi@pobox.com>>.
495
496 =cut
497
498 # eof