# g​o​l​f​ ​a​t​a​n​2

Sometimes it really is a struggle to convert Cartesian coordinates (x,y) to Polar coordinates (r,phi). While you can calculate r = sqrt(x^2+y^2) quite easily, you often need some distinction of cases when calculating the angle phi because arcsin,arccos and arctan and all other trigonometric functions have a co-domain that each only spans half the circle.

In many languages there are built-ins for converting rectangular to polar coordinates, or at least have an atan2 function, which - given (x,y) - calculate the angle phi.

Your task is to write a program/function that takes two (floating point, not both zero) Cartesian coordinates (x,y), and outputs the corresponding polar angle phi, where phi has to be in degrees, radians or grades (with grades I mean gradians which are 1/400 of the full circle), whichever is more convenient for you.

The angle is measured in positive orientation, and we have the zero angle for (1,0).

### Details

You may not use built-ins that calculate the angle phi given two coordinates, including atan2,rect2polar,argOfComplexNumber and similar functions. However you can use the usual trigonometric functions and their reverses, that only take one argument. Any unit symbols are optional.

The radius r must be non-negative, and phi must be in the range [-360°, 360°] (it does not matter whether you output 270° or -90°).

### Examples

Input       Output
(1,1)       45°
(0,3)       90°
(-1,1)      135°
(-5,0)      180°
(-2,-2)     225°
(0,-1.5)    270°
(4,-5)      308.66°

• Required precision in rads/degrees? Jun 18, 2016 at 15:44
• I'd say accurate to about machine precision, depending on what implementation you use (float/double/whatever) Jun 18, 2016 at 15:45
• May we take input as a single complex number?
Dec 3, 2018 at 14:40

# MATL, 12 bytes

yYy/X;0G0<?_


### Explanation

MATL doesn't have an atan function (it has atan2, but it can't be used for this challenge). So I resorted to acos.

y     % Take x, y implicitly. Duplicate x onto the top of the stack
Yy    % Compute hypothenuse from x, y
/     % Divide x by hypothenuse
X;    % Arccosine (inverse of cosine function)
0G    % Push y again
0<    % Is it negative?
?_    % If so, change sign. Implicitly end conditional branch. Implicitly display


• Does matl really have no absolute value builtin? If it does, you could probably use it to replace 0<?_, shaving off a few bytes
– Zwei
Jun 18, 2016 at 16:32
• @Zwei It has (|). But here I'm changing sign of the result based on the sign of the second input, y. Besides, y can be 0, so I can't multiply by y/abs(y)) Jun 18, 2016 at 16:38

## JavaScript (ES6), 50 40 bytes

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)


The result is in radians. Edit: Saved 10 bytes when I noticed that it's allowed for the result to be between -90° and 270°. Previous version with -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)

• What's the ||0 for?
– l4m2
Dec 3, 2018 at 7:49
• @l4m2 For the x=y=0 case.
– Neil
Dec 3, 2018 at 8:55

# MATLAB / Octave, 24 bytes

@(x,y)atan(y/x)+pi*(x<0)


This defines an anonymous function that produces the result in radians.

# Javascript ES6, 54 bytes

(x,y,m=Math)=>x<0&!y?m.PI:m.atan(y/(m.hypot(x,y)+x))*2


# Jelly, 11 bytes (non-competing)

<0×ØP+÷@ÆṬ¥


Output is in radians. Unfortunately, Jelly had a sign bug in its division atoms, making this answer non-competing due to the required bug fix.

Try it online! or verify all test cases (converted to degrees).

### How it works

<0×ØP+÷@ÆṬ¥  Main link. Left argument x. Right argument: y

<0           Compare x with 0.
×ØP        Multiply the resulting Boolean by Pi.
¥  Combine the two links to the left into a dyadic chain.
÷@     Divide y by x.
ÆṬ   Apply arctan to the result.
+       Add the results to both sides.

• Does bugfixing count as making an answer non-competing? That seems odd. If the correct behavior was already specced, the bugfix should be unrelated. (After all, who knows how many other answers you made noncompeting by fixing an unnoticed edge-case?) Jun 19, 2016 at 17:13
• @MarioCarneiro On PPCG, the interpreter defines the language. This is mainly because it's difficult to judge intentions (and most esolangs don't really have a concise spec), while you can't argue with an implementation. Note that altering the interpreter doesn't affect the validity of older answers. They only have to work in some published version of the interpreter. Jun 19, 2016 at 17:15
• I mean that you may have changed the behavior of older answers on some input which was not attempted at the time. How does PPCG handle bad test cases discovered after the fact? Jun 19, 2016 at 17:21
• If test cases prove to be insufficient, more test cases are added. Solutions are expected for all valid inputs, not just the test cases in the question. Re: bug fix. My interpreter only produced the wrong sign for division by 0 (-1÷0 gave inf instead of -inf), so it's unlikely to affect most challenges. Jun 19, 2016 at 17:45

# Python 3, 75 67 bytes

8 bytes thanks to Dennis.

from math import*
lambda x,y:pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2


Ideone it!

• Do you have to write out and and or? Jun 18, 2016 at 16:18
• What else can I do? Jun 18, 2016 at 16:22
• @flawr Python only has and and or. Jun 18, 2016 at 18:33
• pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2 saves a few bytes. Jun 18, 2016 at 18:34
• @flawr: & is a bitwise operator. Jun 18, 2016 at 19:04

# APL (Dyalog Unicode), 12 10 bytesSBCS

-2 thanks to ngn.

Anonymous tacit infix function. Uses alephalpha's formula. Takes x as right argument and y as left argument. Result is in radians.

11○∘⍟0J1⊥,


Try it online!

, concatenate the y and x

0J1⊥ Evaluate as base i digits (i.e. yi¹+xi⁰)

⍟ natural logarithm of that

∘ then

11○ imaginary part of that

• tip
– ngn
Dec 3, 2018 at 10:23
• @ngn Thank you.
Dec 3, 2018 at 13:27
• 11○∘⍟ -> 12○
– ngn
Dec 3, 2018 at 14:33
• @ngn You may not use … argOfComplexNumber
Dec 3, 2018 at 14:39
• oh... i see, sorry
– ngn
Dec 3, 2018 at 14:41

# Mathematica, 16 bytes

I am not sure whether Log is considered as a built-in that calculates the angle given two coordinates.

N@Im@Log[#+I#2]&


### Example:

In[1]:= N@Im@Log[#+I#2]&[1,1]

Out[1]= 0.785398

In[2]:= N@Im@Log[#+I#2]&[4,-5]

Out[2]= -0.896055

• That is a clever idea! Could you add an example how to call this function? May 25, 2017 at 12:50

# x86 machine language (32 bit Linux), 25 13 bytes (noncompeting)

0:       55                      push   %ebp
1:       89 e5                   mov    %esp,%ebp
3:       dd 45 08                fldl   0x8(%ebp)
6:       dd 45 10                fldl   0x10(%ebp)
9:       d9 f3                   fpatan
b:       c9                      leave
c:       c3                      ret


To try it online, compile the following C program (don't forget -m32 flag on x86_64)

#include<stdio.h>
#include<math.h>
const char j[]="U\x89\xe5\335E\b\335E\20\xd9\xf3\xc9\xc3";
int main(){
for(double f=-1;f<1;f+=.1){
for(double g=-1;g<1;g+=.1){
printf("%.2f %.2f %f %f\n",f,g,atan2(f,g),((double(*)(double,double))j)(f,g));
}
}
}


# J, 10 bytes

Anonymous tacit infix function. Uses alephalpha's formula. Takes x as left argument and y as right argument. Result is in radians.

11 o.^.@j.


Try it online!

j. calculate x + y×i

@ then

^. natural logarithm of that

11 o. imaginary part of that

# Pyth, 26 bytes

AQ?|>G0Hy.tcH+@s^R2Q2G5.n0


theta in radians.

Test suite.

# 𝔼𝕊𝕄𝕚𝕟, 13 chars / 17 bytes

î<0)*π+МǍ í/î


Try it here (ES6 browsers only).

Uses (x<0)*pi+tan(y/x).

# Python 3, 65 bytes

from math import*
f=lambda x,y:atan(y/x if x else y*inf)+pi*(x<0)


This outputs radians in the range [-π/2, 3π/2), equivalent to [-90, 270) degrees.

# Axiom, 58 bytes

f(a,b)==(a=0 and b=0=>%i;sign(b)*acos(a*1./sqrt(a^2+b^2)))


test (i use only acos() it returns radiants )

(40) -> [[a,b,f(a,b)*180/%pi] for a in [1,0,-1,-5,-2,0,4] for b in [1,3,1,0,-2,-1.5,-5] ]
(40)
[[1.0,1.0,45.0], [0.0,3.0,90.0], [- 1.0,1.0,135.0], [- 5.0,0.0,180.0],
[- 2.0,- 2.0,- 135.0], [0.0,- 1.5,- 90.0],
[4.0,- 5.0,- 51.3401917459 09909396]]
Type: List List Complex Float


# Python 2, 59 bytes

lambda x,y:acos(x/hypot(x,y))/(-1,1)[y>0]
from math import*


Try it online!

Outputs in radians in range [-pi,pi)