# Cartesian - polar conversion couple

We don't have a challenge for conversion between Cartesian and polar coordinates, so ...

### The challenge

Write two programs (or functions) in the same language:

• one that converts from polar to Cartesian coordinates, and
• the other from Cartesian to polar coodrinates.

The score is the sum of the two program lengths in bytes. Shortest wins.

For reference, the following figure (from the Wikipedia entry linked above) illustrates the relationship between Cartesian coordinates $$\(x, y)\$$ and polar coordinates $$\(r, \varphi)\$$:

• Input and output are flexible as usual, except that they cannot be in the form of complex numbers (which would trivialize the problem). Of course, the program can use complex numbers internally, just not as input or output. Input and output methods can be different for the two programs.

• You can choose to input and output the angle $$\\varphi\$$ either in radians or in degrees; and to limit its values to any 2π-radian or 360º-degree interval.

• Builtins for coordinate conversion are allowed. If you use them, you may want to include another solution without the builtins.

• Floating-point number limitations (accuracy, allowed range of values) are acceptable.

• Programs or functions are allowed. Standard loopholes are forbidden.

### Test cases

Values are shown rounded to 5 decimals. Angles are in radians in the interval $$\[0, 2\pi)\$$.

Cartesian: x, y       <-->      Polar: r, ϕ
------------------              ------------------

2.5, -3.42                       4.23632, -0.93957
3000, -4000                      5000, -0.92730
0, 0                             0, <any>
-2.08073, 4.54649                5, 2
0.07071, 0.07071                 0.1, 0.78540

• Is nan accepted as any value? Aug 10, 2022 at 18:18
• @matteo_c Yes. I assume you mean for output. In fact the angle is undefined when the radius is 0 Aug 10, 2022 at 18:20
• May input / output $r$ be negative?
– tsh
Aug 11, 2022 at 5:55
• @tsh No, r in polar coordinates is nonnegative Aug 11, 2022 at 8:33

# Python, 49 + 48 = 97 bytes

-2 thanks to @Seb

lambda r,a,n=9e9:((x:=r*(a/n-1j)**n).real,x.imag)

Attempt This Online!

lambda x,y,n=1e-9:(abs(c:=x+1j*y),(c**n).imag/n)

Doesn't use any libraries, no exp, no sin, no cos, etc.

### How?

All based on $$\\tan(x)\approx x\quad|x|\ll1\$$ and $$\e^x\approx(1+x/n)^n\quad n\gg 1\$$

• Is there any reason for n=8**9 and n=8**-9 specifically? If not, you could save a byte each with something like n=1e8 and n=7e-9 (particular values chosen to stay close to your original values)
– Seb
Aug 11, 2022 at 14:13
• @Seb Nope, the first should be divisible by 4, but other than that they just ought to be large and small. Aug 11, 2022 at 15:00
• Another cool solution from loopy :+1: Aug 13, 2022 at 10:55

# Wolfram Language (Mathematica), 14+11=25 bytes

AbsArg[#+I#2]&
AngleVector


Try it online!

Input [x,y]/[{r,ϕ}] and output {r,ϕ}/{x,y}.

       #+I#2    convert to complex
AbsArg[     ]   get abs (r) and arg (ϕ)

AngleVector     built-in.


# J 10 (5 + 5)

## to polar, 5 bytes

*.@j.


Try it online!

## to cartesian, 5 bytes

+.@r.


Try it online!

Both of these amount to one built-in for the poler/cc conversion, combined with another builtin for the complex/x-y conversion.

# Desmos, 33+19 = 52 score

Both functions take in two arguments representing either polar or Cartesian coordinates (depending on which function is being used), and returns a list representing the converted coordinates.

### Cartesian to polar: 33 bytes

f(a,b)=[(aa+bb)^{.5},arctan(b,a)]


### Polar to Cartesian: 19 bytes

g(a,b)=[cosb,sinb]a


Try Both Online On Desmos!

Try Both Online On Desmos! - Prettified

# Mathematica, 18+20 = 38 bytes

ToPolarCoordinates

FromPolarCoordinates


Try it online!

For the <any> case, it will output a warning and use Indeterminate.

In some cases, it will not directly return the number, and instead return something like ArcTan[4/3] or 5*Cos[2]. If that's not allowed:

# Mathematica, 21+23 = 44 bytes

N@*ToPolarCoordinates
N@*FromPolarCoordinates


Try it online!

# Pip-p, 10 + 12 = 22 bytes

Polar to Cartesian:

a*[CObSIb]


Takes angle in radians. Outputs a list containing x and y. Try it online!

Cartesian to polar:

PRT$+SQgbATa  Outputs radius and angle (in radians) on separate lines. Try it online! ### Explanations a*[CObSIb] a is radius, b is angle [ ] List containing COb Cosine of b SIb Sine of b a* Multiply each by a PRT$+SQgbATa
a is x-coordinate, b is y-coordinate, g is list containing both
SQg      Square both coordinates
$+ Fold the list of squares on addition RT Square root P Print bATa Two-argument arctangent of b and a Autoprint  # Jelly, 7 + 6 bytes = 13 #### Polar to Cartesian: ×ıÆe×Æi  A dyadic Link accepting $$\\theta\$$ on the left and $$\r\$$ on the right that yields a list $$\[x, y]\$$. Try it online! #### Cartesian to polar: æịA,æA  A dyadic Link accepting $$\y\$$ on the left and $$\x\$$ on the right that yields a list $$\[r, \theta]\$$. Try it online! ### How? ×ıÆe×Æi - Link: theta; r ı - the imaginary unit, i × - (theta) multiplied by (i) Æe - apply the exponential function -> e^(i.theta) × - multiply that by r -> r.e^(i.theta) Æi - Separate that into real and imaginary parts  æịA,æA - Link: y; x æị - y+i.x A - absolute value -> r (same as for x+iy - we've just reflected in Re=Im) æA - atan2(y, x) -> theta (by definition) , - pair  Alternative $$\7\$$ byte Polar to Cartesian: ÆẠ,ÆSƊ× (pair , the cosine ÆẠ and sin ÆS of Ɗ $$\\theta\$$ and multiply × by $$\r\$$). # Factor, 16 + 15 = 31 bytes [ rect> >polar ]  Try it online! [ cis * >rect ]  Try it online! cis does e^(x*i) and cis * is 1 byte shorter than polar>. # x86 64-bit machine code, 23 + 13 = 36 bytes D9 06 D9 07 D9 F3 D9 07 D8 C8 D9 06 D8 C8 DE C1 D9 FA D9 1E D9 1F C3 D9 07 D9 FB D8 0E D9 1F D8 0E D9 1E C3  Try it online! These functions take addresses of two 32-bit floating-point numbers in RDI and RSI, and modify those numbers. The first transforms x,y into ϕ,r and the second does the opposite. In assembly: f: # FPU register stack contents fld DWORD PTR [rsi] # y fld DWORD PTR [rdi] # x y fpatan # ϕ fld DWORD PTR [rdi] # x ϕ fmul st(0), st(0) # x² ϕ fld DWORD PTR [rsi] # y x² ϕ fmul st(0), st(0) # y² x² ϕ faddp # x²+y² ϕ fsqrt # r ϕ fstp DWORD PTR [rsi]# ϕ fstp DWORD PTR [rdi]# ret g: # FPU register stack contents fld DWORD PTR [rdi] # ϕ fsincos # cosϕ sinϕ fmul DWORD PTR [rsi]# x sinϕ fstp DWORD PTR [rdi]# sinϕ fmul DWORD PTR [rsi]# y fstp DWORD PTR [rsi]# ret  • Doesn't this work with any processor all the way back to the 8087? – Neil Aug 11, 2022 at 22:51 • @Neil I guess so. – m90 Aug 12, 2022 at 17:30 • No, it would not, @Neil. One obvious issue is that it uses 64-bit integer registers, which weren't introduced until the x86-64 extensions to the ISA. But another not-so-obvious issue is that it uses the fsincos instruction, which did not exist on the 8087 (wasn't added until the 80387). On the 8087, you were supposed to compute all trigonometric functions via fptan (and inverse trig functions via fpatan), so no sine or cosine functions were included in hardware. So, this could be trivially made to work on the 387 by removing use of 64-bit int registers, but not further back than that. Aug 13, 2022 at 10:46 • @CodyGray I get your point about fsincos, but now that I'm back at a PC, online disassemblers says that those bytes work fine on the '387 with no changes at all (obviously the code uses 32-bit registers in that case), but the 8087 interprets some of those byte sequences differently. – Neil Aug 13, 2022 at 12:33 # Prolog (SWI), 43+37=80 bytes ### Cartesian to Polar, 43 bytes X+Y+R+T:-R is(X^2+Y^2)^0.5,T is atan2(Y,X).  Try it online! ### Polar to Cartesian, 37 bytes R+T+X+Y:-X is R*cos(T),Y is R*sin(T).  Try it online! # MATLAB/Octave, 9+9=18 bytes, builtins Simple builtins, convert between (x,y) and (angle[radians],radius) ### Cartesian to polar: @cart2pol  Try it online! ### Polar to cartesian: @pol2cart  Try it online! # 23+29=52 bytes, without builtins Same input/output as before ### Cartesian to polar: @(x,y)[atan2(y,x),abs(x+y*i)]  Try it online! ### Polar to cartesian: @(a,r)r*[cos(a),sin(a)]  Try it online! # Python, 48+48 = 96 bytes lambda*t:(hypot(*t),atan2(*t)) from math import* Attempt This Online! -4 bytes thanks to xnor. lambda a,b:(a*cos(b),a*sin(b)) from math import* Attempt This Online! • Are you allowed to share the from math import* between the two functions? Aug 10, 2022 at 18:59 • I don't think so. Aug 10, 2022 at 19:01 • 48 for the first one lambda*t:(hypot(*t),atan2(*t)) from math import* – xnor Aug 10, 2022 at 22:56 # SageMath, 69 68 bytes lambda x,y:((x^2+y^2)^.5,arctan2(y,x)) lambda r,t:(r*cos(t),r*sin(t))  Try it online! Adjusted score correctly thanks to Steffan. Saved a byte thanks to Luis Mendo!!! • This is 69 bytes. You don't count the p=, c=, or the newline Aug 10, 2022 at 22:05 • @Steffan Easiest golf ever - thanks! :D Aug 10, 2022 at 23:37 # R, 30+24=54 bytes ### Cartesian to polar, 30 bytes \(x,y)c(Mod(z<-x+1i*y),Arg(z)) Attempt This Online! No imaginary numbers for +2: \(x,y)c((x^2+y^2)^.5,atan2(y,x)) Attempt This Online! ### Polar to cartesian, 24 bytes \(r,a)r*c(cos(a),sin(a)) Attempt This Online! # 05AB1E (legacy), 7 + 22 = 29 bytes ### Polar to Cartesian (7 bytes): .¾¹.½‚*  Loose inputs in the order $$\\phi,r\$$; outputs as a pair $$\[x,y]\$$. ### Cartesian to Polar (22 bytes): nOtI’£×.aÇâ2(ÿ,ÿ)’.E‚  Input as a pair in the order $$\[x,y]\$$; outputs as a pair $$\[r,\phi]\$$. Explanation: .¾ # Calculate the cosine of the first (implicit) input ϕ ¹.½ # Also push the sine of the first input ϕ ‚ # Pair them together * # Multiply them to the second (implicit) input r # (after which the pair is output implicitly as result)  Although 05AB1E does have tangent, sine, and cosine builtins, it lacks arctan; arcsin; and arccos builtins (both with 1 or 2 arguments). So we'll use a Python eval for it instead (hence the use of the legacy version of 05AB1E)†: n # Get the square of the values in the (implicit) input-pair [y,x] O # Sum them together t # Take the square root of that I # Push the input-pair [x,y]  # Pop and push both separated to the stack ’£×.aÇâ2(ÿ,ÿ)’ # Push dictionary string "math.atan2(ÿ,ÿ)", # where the two ÿ are replaced with y,x respectively .E # Evaluate and execute it as Python code ‚ # Pair it with the earlier calculated sqrt(y²+x²) # (after which it is output implicitly as result)  See this 05AB1E tip of mine (section How to use the dictionary?) to understand why ’£×.aÇâ2(ÿ,ÿ)’ is "math.atan2(ÿ,ÿ)". † The new version of 05AB1E is possible as well, but .E is eval as Elixir instead of Python, in which case the math.atan2(a,b) would be :math.atan2(a,b), which is 1 byte longer. # Lua, 41 + 41 = 82 bytes Cartesian to Polar, 41 bytes x,y=...print((x^2+y^2)^.5,math.atan(y,x))  Try it online! Polar to Cartesian, 41 bytes r,t=...print(r*math.cos(t),r*math.sin(t))  Try it online! # Vyxal, 10 + 7 = 17 bytes ## Cartesian to Polar, 10 bytes ²∑√?Ṙƒ/∆T"  Try it Online! ## Polar to Cartesian, 7 bytes ⁰₍∆c∆s*  Try it Online! # C (gcc), 88 bytes C(x,b,t)float*x,t;{t=x[1];x[1]=b?*x*sin(t):atan(t/(*x));*x=b?*x*cos(t):sqrt(*x**x+t*t);}  # 86 bytes 2 bytes can be saved by inverting the order of the cartesian coordinates, that is, $$\(y, x)\$$ instead of $$\(x, y)\$$, C(x,b,t)float*x,t;{t=x[1];x[1]=b?*x*cos(t):atan(*x/t);*x=b?*x*sin(t):sqrt(*x**x+t*t);}  Try it online! Pointer x is used for both input and output. b specifies which conversion must be applied (0 for cartesian to polar, any non-zero value for polar to cartesian). The solution is not made up by two different functions, but I think should be acceptable. # 62 + 53 = 115 bytes As two separate functions: A(x,t)float*x,t;{t=x[1];x[1]=atan(t/(*x));*x=sqrt(*x**x+t*t);} B(x,t)float*x,t;{t=x[1];x[1]=*x*sin(t);*x=*x*cos(t);}  Try it online! 2 bytes can be saved using the same trick as above described. • I like the idea of using the same function, but I’m afraid that goes against the challenge rules (you would have to count it twice, and the additional input is not allowed) Aug 10, 2022 at 18:50 • Suggest hypot(x,y) instead of sqrt(x*x+y*y) and *x*=cos(t) instead of *x=*x*cos(t) Aug 11, 2022 at 7:31 # lin, 28 + 17 = 45 bytes To Polar ([a b] -> [a b]): "2^.$_ +.5^"".$_.~ atant", Q  To Cartesian (a b -> [a b]): "cos *""sin *", Q  Try it here! For testing purposes: [2.5 3.42_ ][3000 4000_ ][0 0][2.08073_ 4.54649][0.07071 0.07071] ; ( ;.+.$_.; \form.'. " -> "join outln ).'
"2^.$_ +.5^"".$_.~ atant", Q
"cos *""sin *", Q


## Explanation

Prettified code:

( 2^.$_ + .5^ )(.$_.~ atant ) , Q
( cos * )( sin * ) , '


Both of these expressions utilize a somewhat odd feature of lin. Data structures of strings/functions* passed to certain commands will "fork" and execute each function, preserving the structure's shape. For example:

1 2 [( 1+ )( 2+ )] es


would leave on the stack:

1 2 [[1 3] [1 4]]


The Q command ("quarantine") executes a function on an isolated copy of the current stack and pushes the resulting top item. So the following:

1 2 [( 1+ )( 2+ )] Q


would leave on the stack:

1 2 [3 4]


*: In lin, strings and functions are the same datatype.

# PARI/GP, 34 + 24 = 58 bytes

f(x,y)=[abs(z=x+I*y),if(z,arg(z))]
g(r,a)=r*[cos(a),sin(a)]

Attempt This Online!