MJ -- To determine the difference between two directions on a compass the proc below can be used. It can most likely be written shorter, but it should at least give the correct answer.
For two compass courses $a and $b it will calculate the difference in degrees and whether you need to go clockwise (positive return) or counterclockwise (negative return) to go from course $a to $b.
proc anglediff {a b} {
set a [expr {$a%360}]
set b [expr {$b%360}]
set dclockwise [expr (360-$a+$b)%360]
return [expr {$dclockwise<=180?$dclockwise:-(360-$dclockwise)}]
}
# and some tests:
proc assert_equal {a b} {
if {$a != $b} { error "assertion $a==$b failed"}
}
assert_equal [anglediff 1 359] -2
assert_equal [anglediff 0 180] 180
assert_equal [anglediff -10 10] 20
assert_equal [anglediff 360 0] 0
assert_equal [anglediff 180 -180] 0
assert_equal [anglediff -10 340] -10
dzach I use a similar routine often. Only, to make it work with decimal angles, one has to use fmod():
proc anglediff {a b} {
set dclockwise [expr {fmod(360-fmod($a,360)+fmod($b,360),360)}]
expr {$dclockwise<=180?$dclockwise:-(360-$dclockwise)}
}
% anglediff 1 359
-2.0
% time {anglediff 1 359} 1000
3.232 microseconds per iteration
To make it faster, I use C and
critcl:
critcl::cproc dcourse {double a double b} double {
double dc = fmod(360.0 - fmod(a,360) + fmod(b,360), 360);
return dc <= 180 ? dc : dc - 360;
}
% load ./dcourse.so
% dcourse 1 359
-2.0
% time {dcourse 1 359} 1000
0.782 microseconds per iteration