Commit | Line | Data |
5aabfad6 |
1 | #!./perl |
2 | |
3 | # |
4 | # Regression tests for the Math::Trig package |
5 | # |
bf5f1b4c |
6 | # The tests here are quite modest as the Math::Complex tests exercise |
7 | # these interfaces quite vigorously. |
5aabfad6 |
8 | # |
9 | # -- Jarkko Hietaniemi, April 1997 |
10 | |
11 | BEGIN { |
bf5f1b4c |
12 | if ($ENV{PERL_CORE}) { |
13 | chdir 't' if -d 't'; |
14 | @INC = '../lib'; |
15 | } |
5aabfad6 |
16 | } |
17 | |
bf5f1b4c |
18 | use Math::Trig 1.03; |
19 | |
20 | my $pip2 = pi / 2; |
5aabfad6 |
21 | |
22 | use strict; |
23 | |
24 | use vars qw($x $y $z); |
25 | |
26 | my $eps = 1e-11; |
27 | |
2f367121 |
28 | if ($^O eq 'unicos') { # See lib/Math/Complex.pm and t/lib/complex.t. |
29 | $eps = 1e-10; |
30 | } |
31 | |
5aabfad6 |
32 | sub near ($$;$) { |
e64f0054 |
33 | my $e = defined $_[2] ? $_[2] : $eps; |
d139edd6 |
34 | print "# near? $_[0] $_[1] $e\n"; |
e64f0054 |
35 | $_[1] ? (abs($_[0]/$_[1] - 1) < $e) : abs($_[0]) < $e; |
5aabfad6 |
36 | } |
37 | |
bf5f1b4c |
38 | print "1..49\n"; |
5aabfad6 |
39 | |
40 | $x = 0.9; |
41 | print 'not ' unless (near(tan($x), sin($x) / cos($x))); |
42 | print "ok 1\n"; |
43 | |
44 | print 'not ' unless (near(sinh(2), 3.62686040784702)); |
45 | print "ok 2\n"; |
46 | |
47 | print 'not ' unless (near(acsch(0.1), 2.99822295029797)); |
48 | print "ok 3\n"; |
49 | |
50 | $x = asin(2); |
51 | print 'not ' unless (ref $x eq 'Math::Complex'); |
52 | print "ok 4\n"; |
53 | |
54 | # avoid using Math::Complex here |
55 | $x =~ /^([^-]+)(-[^i]+)i$/; |
56 | ($y, $z) = ($1, $2); |
57 | print 'not ' unless (near($y, 1.5707963267949) and |
58 | near($z, -1.31695789692482)); |
59 | print "ok 5\n"; |
60 | |
ace5de91 |
61 | print 'not ' unless (near(deg2rad(90), pi/2)); |
5aabfad6 |
62 | print "ok 6\n"; |
63 | |
ace5de91 |
64 | print 'not ' unless (near(rad2deg(pi), 180)); |
65 | print "ok 7\n"; |
66 | |
d54bf66f |
67 | use Math::Trig ':radial'; |
68 | |
69 | { |
70 | my ($r,$t,$z) = cartesian_to_cylindrical(1,1,1); |
71 | |
72 | print 'not ' unless (near($r, sqrt(2))) and |
73 | (near($t, deg2rad(45))) and |
74 | (near($z, 1)); |
75 | print "ok 8\n"; |
76 | |
77 | ($x,$y,$z) = cylindrical_to_cartesian($r, $t, $z); |
78 | |
79 | print 'not ' unless (near($x, 1)) and |
80 | (near($y, 1)) and |
81 | (near($z, 1)); |
82 | print "ok 9\n"; |
83 | |
84 | ($r,$t,$z) = cartesian_to_cylindrical(1,1,0); |
85 | |
86 | print 'not ' unless (near($r, sqrt(2))) and |
87 | (near($t, deg2rad(45))) and |
88 | (near($z, 0)); |
89 | print "ok 10\n"; |
90 | |
91 | ($x,$y,$z) = cylindrical_to_cartesian($r, $t, $z); |
92 | |
93 | print 'not ' unless (near($x, 1)) and |
94 | (near($y, 1)) and |
95 | (near($z, 0)); |
96 | print "ok 11\n"; |
97 | } |
98 | |
99 | { |
100 | my ($r,$t,$f) = cartesian_to_spherical(1,1,1); |
101 | |
102 | print 'not ' unless (near($r, sqrt(3))) and |
103 | (near($t, deg2rad(45))) and |
104 | (near($f, atan2(sqrt(2), 1))); |
105 | print "ok 12\n"; |
106 | |
107 | ($x,$y,$z) = spherical_to_cartesian($r, $t, $f); |
108 | |
109 | print 'not ' unless (near($x, 1)) and |
110 | (near($y, 1)) and |
111 | (near($z, 1)); |
112 | print "ok 13\n"; |
113 | |
114 | ($r,$t,$f) = cartesian_to_spherical(1,1,0); |
115 | |
116 | print 'not ' unless (near($r, sqrt(2))) and |
117 | (near($t, deg2rad(45))) and |
118 | (near($f, deg2rad(90))); |
119 | print "ok 14\n"; |
120 | |
121 | ($x,$y,$z) = spherical_to_cartesian($r, $t, $f); |
122 | |
123 | print 'not ' unless (near($x, 1)) and |
124 | (near($y, 1)) and |
125 | (near($z, 0)); |
126 | print "ok 15\n"; |
127 | } |
128 | |
129 | { |
130 | my ($r,$t,$z) = cylindrical_to_spherical(spherical_to_cylindrical(1,1,1)); |
131 | |
132 | print 'not ' unless (near($r, 1)) and |
133 | (near($t, 1)) and |
134 | (near($z, 1)); |
135 | print "ok 16\n"; |
136 | |
137 | ($r,$t,$z) = spherical_to_cylindrical(cylindrical_to_spherical(1,1,1)); |
138 | |
139 | print 'not ' unless (near($r, 1)) and |
140 | (near($t, 1)) and |
141 | (near($z, 1)); |
142 | print "ok 17\n"; |
143 | } |
144 | |
145 | { |
9db5a202 |
146 | use Math::Trig 'great_circle_distance'; |
d54bf66f |
147 | |
9db5a202 |
148 | print 'not ' |
149 | unless (near(great_circle_distance(0, 0, 0, pi/2), pi/2)); |
150 | print "ok 18\n"; |
d54bf66f |
151 | |
9db5a202 |
152 | print 'not ' |
153 | unless (near(great_circle_distance(0, 0, pi, pi), pi)); |
154 | print "ok 19\n"; |
d54bf66f |
155 | |
9db5a202 |
156 | # London to Tokyo. |
157 | my @L = (deg2rad(-0.5), deg2rad(90 - 51.3)); |
158 | my @T = (deg2rad(139.8),deg2rad(90 - 35.7)); |
d54bf66f |
159 | |
9db5a202 |
160 | my $km = great_circle_distance(@L, @T, 6378); |
d54bf66f |
161 | |
9db5a202 |
162 | print 'not ' unless (near($km, 9605.26637021388)); |
163 | print "ok 20\n"; |
164 | } |
165 | |
166 | { |
fdf27e67 |
167 | my $R2D = 57.295779513082320876798154814169; |
168 | |
169 | sub frac { $_[0] - int($_[0]) } |
170 | |
9db5a202 |
171 | my $lotta_radians = deg2rad(1E+20, 1); |
fdf27e67 |
172 | print "not " unless near($lotta_radians, 1E+20/$R2D); |
9db5a202 |
173 | print "ok 21\n"; |
174 | |
175 | my $negat_degrees = rad2deg(-1E20, 1); |
fdf27e67 |
176 | print "not " unless near($negat_degrees, -1E+20*$R2D); |
9db5a202 |
177 | print "ok 22\n"; |
178 | |
179 | my $posit_degrees = rad2deg(-10000, 1); |
fdf27e67 |
180 | print "not " unless near($posit_degrees, -10000*$R2D); |
9db5a202 |
181 | print "ok 23\n"; |
d54bf66f |
182 | } |
183 | |
7e5f197a |
184 | { |
185 | use Math::Trig 'great_circle_direction'; |
186 | |
187 | print 'not ' |
188 | unless (near(great_circle_direction(0, 0, 0, pi/2), pi)); |
189 | print "ok 24\n"; |
190 | |
bf5f1b4c |
191 | # Retired test: Relies on atan2(0, 0), which is not portable. |
3e5d91f1 |
192 | # print 'not ' |
193 | # unless (near(great_circle_direction(0, 0, pi, pi), -pi()/2)); |
7e5f197a |
194 | print "ok 25\n"; |
195 | |
d139edd6 |
196 | my @London = (deg2rad( -0.167), deg2rad(90 - 51.3)); |
197 | my @Tokyo = (deg2rad( 139.5), deg2rad(90 - 35.7)); |
198 | my @Berlin = (deg2rad ( 13.417), deg2rad(90 - 52.533)); |
199 | my @Paris = (deg2rad ( 2.333), deg2rad(90 - 48.867)); |
7e5f197a |
200 | |
d139edd6 |
201 | print 'not ' |
202 | unless (near(rad2deg(great_circle_direction(@London, @Tokyo)), |
203 | 31.791945393073)); |
7e5f197a |
204 | print "ok 26\n"; |
bf5f1b4c |
205 | |
d139edd6 |
206 | print 'not ' |
207 | unless (near(rad2deg(great_circle_direction(@Tokyo, @London)), |
208 | 336.069766430326)); |
209 | print "ok 27\n"; |
210 | |
211 | print 'not ' |
212 | unless (near(rad2deg(great_circle_direction(@Berlin, @Paris)), |
213 | 246.800348034667)); |
214 | |
215 | print "ok 28\n"; |
bf5f1b4c |
216 | |
d139edd6 |
217 | print 'not ' |
218 | unless (near(rad2deg(great_circle_direction(@Paris, @Berlin)), |
219 | 58.2079877553156)); |
220 | print "ok 29\n"; |
bf5f1b4c |
221 | |
222 | use Math::Trig 'great_circle_bearing'; |
223 | |
224 | print 'not ' |
225 | unless (near(rad2deg(great_circle_bearing(@Paris, @Berlin)), |
226 | 58.2079877553156)); |
227 | print "ok 30\n"; |
228 | |
229 | use Math::Trig 'great_circle_waypoint'; |
230 | use Math::Trig 'great_circle_midpoint'; |
231 | |
232 | my ($lon, $lat); |
233 | |
234 | ($lon, $lat) = great_circle_waypoint(@London, @Tokyo, 0.0); |
235 | |
236 | print 'not ' unless (near($lon, $London[0])); |
237 | print "ok 31\n"; |
238 | |
239 | print 'not ' unless (near($lat, $pip2 - $London[1])); |
240 | print "ok 32\n"; |
241 | |
242 | ($lon, $lat) = great_circle_waypoint(@London, @Tokyo, 1.0); |
243 | |
244 | print 'not ' unless (near($lon, $Tokyo[0])); |
245 | print "ok 33\n"; |
246 | |
247 | print 'not ' unless (near($lat, $pip2 - $Tokyo[1])); |
248 | print "ok 34\n"; |
249 | |
250 | ($lon, $lat) = great_circle_waypoint(@London, @Tokyo, 0.5); |
251 | |
252 | print 'not ' unless (near($lon, 1.55609593577679)); # 89.1577 E |
253 | print "ok 35\n"; |
254 | |
255 | print 'not ' unless (near($lat, 1.20296099733328)); # 68.9246 N |
256 | print "ok 36\n"; |
257 | |
258 | ($lon, $lat) = great_circle_midpoint(@London, @Tokyo); |
259 | |
260 | print 'not ' unless (near($lon, 1.55609593577679)); # 89.1577 E |
261 | print "ok 37\n"; |
262 | |
263 | print 'not ' unless (near($lat, 1.20296099733328)); # 68.9246 N |
264 | print "ok 38\n"; |
265 | |
266 | ($lon, $lat) = great_circle_waypoint(@London, @Tokyo, 0.25); |
267 | |
268 | print 'not ' unless (near($lon, 0.516073562850837)); # 29.5688 E |
269 | print "ok 39\n"; |
270 | |
271 | print 'not ' unless (near($lat, 1.170565013391510)); # 67.0684 N |
272 | print "ok 40\n"; |
273 | ($lon, $lat) = great_circle_waypoint(@London, @Tokyo, 0.75); |
274 | |
275 | print 'not ' unless (near($lon, 2.17494903805952)); # 124.6154 E |
276 | print "ok 41\n"; |
277 | |
278 | print 'not ' unless (near($lat, 0.952987032741305)); # 54.6021 N |
279 | print "ok 42\n"; |
280 | |
281 | use Math::Trig 'great_circle_destination'; |
282 | |
283 | my $dir1 = great_circle_direction(@London, @Tokyo); |
284 | my $dst1 = great_circle_distance(@London, @Tokyo); |
285 | |
286 | ($lon, $lat) = great_circle_destination(@London, $dir1, $dst1); |
287 | |
288 | print 'not ' unless (near($lon, $Tokyo[0])); |
289 | print "ok 43\n"; |
290 | |
291 | print 'not ' unless (near($lat, $pip2 - $Tokyo[1])); |
292 | print "ok 44\n"; |
293 | |
294 | my $dir2 = great_circle_direction(@Tokyo, @London); |
295 | my $dst2 = great_circle_distance(@Tokyo, @London); |
296 | |
297 | ($lon, $lat) = great_circle_destination(@Tokyo, $dir2, $dst2); |
298 | |
299 | print 'not ' unless (near($lon, $London[0])); |
300 | print "ok 45\n"; |
301 | |
302 | print 'not ' unless (near($lat, $pip2 - $London[1])); |
303 | print "ok 46\n"; |
304 | |
305 | my $dir3 = (great_circle_destination(@London, $dir1, $dst1))[2]; |
306 | |
307 | print 'not ' unless (near($dir3, 2.69379263839118)); # about 154.343 deg |
308 | print "ok 47\n"; |
309 | |
310 | my $dir4 = (great_circle_destination(@Tokyo, $dir2, $dst2))[2]; |
311 | |
312 | print 'not ' unless (near($dir4, 3.6993902625701)); # about 211.959 deg |
313 | print "ok 48\n"; |
314 | |
315 | print 'not ' unless (near($dst1, $dst2)); |
316 | print "ok 49\n"; |
7e5f197a |
317 | } |
318 | |
5aabfad6 |
319 | # eof |