While q/k offers all the standard trigonometric functions, it does not include
atan2. A recent project (calculating headings between airports) required
atan2; therefore I needed to implement it.
Wikipedia was my guide and my first attempt was a pretty straight-forward implementation in k:
atan2:{[y;x]
p: $[y>0;pi;y<0;0-pi;0N];
$[
x>0; atan[y%x];
x<0; atan[y%x]+p;
x=0; p%2;
0N;
]
}
This works but the excitement faded when I realized $[] only works with
scalars.
Re-examining the atan2 rules, we can create this chart:
x > 0 |
x < 0 |
x = 0 |
|
y > 0 |
atan[y%x] |
atan[y%x] + pi |
+pi%2 |
y < 0 |
atan[y%x] |
atan[y%x] - pi |
-pi%2 |
y = 0 |
atan[y%x] |
atan[y%x] + pi |
undefined |
The most difficult case is x = 0. Fortunately, k’s atan gives the correct
result for +infinity, -infinity, and null, so it can ignore x = 0 and y = 0
x >= 0 |
x < 0 |
|
y >= 0 |
atan[y%x] |
atan[y%x] + pi |
y < 0 |
atan[y%x] |
atan[y%x] - pi |
Our only concern is adding (or substracting) pi when x < 0:
atan2:{[y;x]
fudge: pi * (x<0) * (2*y>=0)-1;
fudge + atan[y%x]
}