From 9db5a202456c4160bf9108553745252960c7c050 Mon Sep 17 00:00:00 2001 From: Jarkko Hietaniemi Date: Fri, 25 Aug 2000 23:54:34 +0000 Subject: [PATCH] Support preserving extremely big/small angles. p4raw-id: //depot/perl@6827 --- lib/Math/Trig.pm | 43 +++++++++++++++++++++++++++++-------------- pod/perldelta.pod | 5 +++-- t/lib/trig.t | 48 ++++++++++++++++++++++++++++++++++-------------- 3 files changed, 66 insertions(+), 30 deletions(-) diff --git a/lib/Math/Trig.pm b/lib/Math/Trig.pm index 492706c..b28f150 100644 --- a/lib/Math/Trig.pm +++ b/lib/Math/Trig.pm @@ -36,14 +36,15 @@ my @rdlcnv = qw(cartesian_to_cylindrical %EXPORT_TAGS = ('radial' => [ @rdlcnv ]); -sub pi2 () { 2 * pi } # use constant generates warning -sub pip2 () { pi / 2 } # use constant generates warning -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 pi2 () { 2 * pi } +sub pip2 () { pi / 2 } + +sub DR () { pi2/360 } +sub RD () { 360/pi2 } +sub DG () { 400/360 } +sub GD () { 360/400 } +sub RG () { 400/pi2 } +sub GR () { pi2/400 } # # Truncating remainder. @@ -58,17 +59,23 @@ sub remt ($$) { # Angle conversions. # -sub rad2deg ($) { remt(RD * $_[0], 360) } +sub rad2rad($) { remt($_[0], pi2) } + +sub deg2deg($) { remt($_[0], 360) } + +sub grad2grad($) { remt($_[0], 400) } -sub deg2rad ($) { remt(DR * $_[0], pi2) } +sub rad2deg ($;$) { my $d = RD * $_[0]; $_[1] ? $d : deg2deg($d) } -sub grad2deg ($) { remt(GD * $_[0], 360) } +sub deg2rad ($;$) { my $d = DR * $_[0]; $_[1] ? $d : rad2rad($d) } -sub deg2grad ($) { remt(DG * $_[0], 400) } +sub grad2deg ($;$) { my $d = GD * $_[0]; $_[1] ? $d : deg2deg($d) } -sub rad2grad ($) { remt(RG * $_[0], 400) } +sub deg2grad ($;$) { my $d = DG * $_[0]; $_[1] ? $d : grad2grad($d) } -sub grad2rad ($) { remt(GR * $_[0], pi2) } +sub rad2grad ($;$) { my $d = RG * $_[0]; $_[1] ? $d : grad2grad($d) } + +sub grad2rad ($;$) { my $d = GR * $_[0]; $_[1] ? $d : rad2rad($d) } sub cartesian_to_spherical { my ( $x, $y, $z ) = @_; @@ -280,6 +287,14 @@ and the imaginary part of approximately C<-1.317>. $gradians = rad2grad($radians); The full circle is 2 I radians or I<360> degrees or I<400> gradians. +The result is by default wrapped to be inside the [0, {2pi,360,400}[ circle. +If you don't want this, supply a true second argument: + + $zillions_of_radians = deg2rad($zillions_of_degrees, 1); + $negative_degrees = rad2deg($negative_radians, 1); + +You can also do the wrapping explicitly by rad2rad(), deg2deg(), and +grad2grad(). =head1 RADIAL COORDINATE CONVERSIONS diff --git a/pod/perldelta.pod b/pod/perldelta.pod index c496caf..e1d7b18 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -155,8 +155,9 @@ the podlators bundle, Pod::LaTeX, Pod::Parser, Term::ANSIColor, Test. =item * Bug fixes and minor enhancements have been applied to B::Deparse, -Data::Dumper, IO::Poll, IO::Socket::INET, Math::BigFloat, Math::Complex, -re, SelfLoader, Sys::SysLog, Test::Harness, Text::Wrap, UNIVERSAL. +Data::Dumper, IO::Poll, IO::Socket::INET, Math::BigFloat, +Math::Complex, Math::Trig, re, SelfLoader, Sys::SysLog, Test::Harness, +Text::Wrap, UNIVERSAL. =item * diff --git a/t/lib/trig.t b/t/lib/trig.t index 20669f0..b68eb02 100755 --- a/t/lib/trig.t +++ b/t/lib/trig.t @@ -29,7 +29,7 @@ sub near ($$;$) { abs($_[0] - $_[1]) < (defined $_[2] ? $_[2] : $eps); } -print "1..20\n"; +print "1..23\n"; $x = 0.9; print 'not ' unless (near(tan($x), sin($x) / cos($x))); @@ -137,24 +137,44 @@ use Math::Trig ':radial'; } { - use Math::Trig 'great_circle_distance'; + use Math::Trig 'great_circle_distance'; - print 'not ' - unless (near(great_circle_distance(0, 0, 0, pi/2), pi/2)); - print "ok 18\n"; + print 'not ' + unless (near(great_circle_distance(0, 0, 0, pi/2), pi/2)); + print "ok 18\n"; - print 'not ' - unless (near(great_circle_distance(0, 0, pi, pi), pi)); - print "ok 19\n"; + print 'not ' + unless (near(great_circle_distance(0, 0, pi, pi), pi)); + print "ok 19\n"; - # London to Tokyo. - my @L = (deg2rad(-0.5), deg2rad(90 - 51.3)); - my @T = (deg2rad(139.8),deg2rad(90 - 35.7)); + # London to Tokyo. + my @L = (deg2rad(-0.5), deg2rad(90 - 51.3)); + my @T = (deg2rad(139.8),deg2rad(90 - 35.7)); - my $km = great_circle_distance(@L, @T, 6378); + my $km = great_circle_distance(@L, @T, 6378); - print 'not ' unless (near($km, 9605.26637021388)); - print "ok 20\n"; + print 'not ' unless (near($km, 9605.26637021388)); + print "ok 20\n"; +} + +{ + my $lotta_radians = deg2rad(1E+20, 1); + print "not " unless near($lotta_radians, 1E+20/57.29577951308232087721); + print "ok 21\n"; + + my $negat_degrees = rad2deg(-1E20, 1); + print "not " unless near($negat_degrees, -1E+20*57.29577951308232087721); + print "ok 22\n"; + + my $posit_degrees = rad2deg(-10000, 1); + print "not " unless near($posit_degrees, -10000*57.29577951308232087721); + + print "ok 23\n"; + + my $posiu_degrees = rad2deg(-10000, 0); + print "not " unless near($posiu_degrees, -197.795130823273); + + print "ok 24\n"; } # eof -- 2.7.4