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