# File: AngularDifference.pm package AngularDifference; BEGIN { use Exporter; our @ISA = qw( Exporter ); our @EXPORT = qw( &angdiff ); } # compute the difference between angles \$a and \$b sub angdiff(\$\$) { my (\$a, \$b) = @_; return abs(\$a - \$b) % 360; } 1; ##```## # File: AngularDifference.t use AngularDifference; # provides angdiff use Test::More tests => 6; # identical angles should have a diff of zero is( angdiff( 0, 0), # observed result 0, # expected result "zero at 0" # name of the test case ); # case 1 is( angdiff( 90, 90), 0, "zero at 90" ); # case 2 # order of angles shouldn't matter to diff is( angdiff( 0, 45), 45, "0,45 -> 45" ); # case 3 is( angdiff( 45, 0), 45, "45,0 -> 45" ); # case 4 # should return the smallest angle between is( angdiff( 0,270), 90, "0,270 -> 90, not 270" ); # case 5 # multiples of 360-degrees shouldn't matter my (\$a,\$b) = (360 * 2, 360 * 4); is( angdiff(\$a,\$b+23),23, "\$a,\$b+23 -> 23" ); # case 6 ##``````## \$ perl AngularDifference.t 1..6 ok 1 - zero at zero ok 2 - zero at 90 ok 3 - 0,45 -> 45 ok 4 - 45,0 -> 45 not ok 5 - 0,270 -> 90, not 270 # Failed test (AngularDifference.t at line 15) # got: '270' # expected: '90' ok 6 - 720,1440+23 -> 23 # Looks like you failed 1 tests of 6. ##``````## sub angdiff(\$\$) { my (\$a, \$b) = @_; return abs(\$a - \$b) % 180; } ##``````## \$ perl AngularDifference.t 1..6 ok 1 - zero at zero ok 2 - zero at 90 ok 3 - 0,45 -> 45 ok 4 - 45,0 -> 45 ok 5 - 0,270 -> 90, not 270 ok 6 - 720,1440+23 -> 23 ##``````## is( angdiff( 90, 90), 0, "zero at 90" ); # case 2 ##``````## # File: AngularDifference.l.t use AngularDifference; use Test::LectroTest; Property { ##[ a <- Int, diff <- Int(range=>[-180,180]) ]## angdiff(\$a, \$a + \$diff) == abs(\$diff) }, name => "angdiff holds to defn of angular difference"; ##``````## ##[ a <- Int, diff <- Int(range=>[-180,180]) ]## ##``````## angdiff(\$a, \$a + \$diff) == abs(\$diff) ##``````## \$ perl AngularDifference.l.t 1..1 not ok 1 - 'angdiff holds to defn of angular difference' falsified in 535 attempts # Counterexample: # \$a = 148; # \$diff = 180; ##``````## When \$a = 0 And \$b is The expected And angdiff result is returns ========= ============ =========== 150 150 150 160 160 160 170 170 170 180 180 0 <-- Oops 190 170 10 <-- Oops 200 160 20 <-- Oops 210 150 30 <-- Oops ##``````## sub angdiff(\$\$) { my (\$a, \$b) = @_; my \$delta = (\$a - \$b) % 360; return \$delta > 180 ? 360 - \$delta : \$delta; } ##``````## \$ perl AngularDifference.l.t 1..1 ok 1 - 'angdiff holds to defn of angular difference' (1000 attempts) ##``````## Property { ##[ a <- Int, diff <- Int(range=>[-180,180]) ]## if (\$diff == 0) { \$tcon->label("zero") } elsif (abs(\$diff) <= 90) { \$tcon->label("1 to 90") } elsif (abs(\$diff) <= 180) { \$tcon->label("91 to 180") } elsif (abs(\$diff) <= 360) { \$tcon->label("181 to 360") } else { \$tcon->label("> 360") } angdiff(\$a, \$a + \$diff) == abs(\$diff) }, name => "angdiff holds to defn of angular difference"; ##``````## 1..1 ok 1 - 'angdiff holds to defn of angular difference' (1000 attempts) # 58% 1 to 90 # 41% 91 to 180 # 0% zero ##``````## Property { ##[ a <- Int, n <- Int, diff <- Int(range=>[-180,180]) ]## my \$b = \$a + 360*\$n + \$diff; my \$delta = abs(\$b - \$a); if (\$delta == 0) { \$tcon->label("zero") } elsif (\$delta <= 90) { \$tcon->label("1 to 90") } elsif (\$delta <= 180) { \$tcon->label("91 to 180") } elsif (\$delta <= 360) { \$tcon->label("181 to 360") } else { \$tcon->label("> 360") } angdiff(\$a, \$b) == abs(\$diff) }, name => "angdiff holds to defn of angular difference"; ##``````## 1..1 ok 1 - 'angdiff holds to defn of angular difference' (1000 attempts) # 98% > 360 # 0% 181 to 360 # 0% 1 to 90 ##``````## n <- OneOf( Int(range=>[-1,1]), Int ) ##``````## Property { ##[ a <- Int, n <- OneOf( Int(range=>[-1,1]), Int ), diff <- Int( range=>[-180,180] ) ]## my \$b = \$a + 360*\$n + \$diff; my \$delta = abs(\$b - \$a); if (\$delta == 0) { \$tcon->label("zero") } elsif (\$delta <= 90) { \$tcon->label("1 to 90") } elsif (\$delta <= 180) { \$tcon->label("91 to 180") } elsif (\$delta <= 360) { \$tcon->label("181 to 360") } else { \$tcon->label("> 360") } angdiff(\$a, \$b) == abs(\$diff) }, name => "angdiff holds to defn of angular difference"; ##``````## 1..1 ok 1 - 'angdiff holds to defn of angular difference' (1000 attempts) # 67% > 360 # 17% 181 to 360 # 9% 1 to 90 # 6% 91 to 180 # 0% zero ##``````## n <- Frequency( [20,Int(range=>[-1,1])], [1,Int] ) ##``````## 1..1 ok 1 - 'angdiff holds to defn of angular difference' (1000 attempts) # 37% > 360 # 32% 181 to 360 # 18% 1 to 90 # 10% 91 to 180 # 0% zero ```