Python conversion between coordinates
PythonCoordinate SystemsPython Problem Overview
Are there functions for conversion between different coordinate systems?
For example, Matlab has [rho,phi] = cart2pol(x,y)
for conversion from cartesian to polar coordinates. Seems like it should be in numpy or scipy.
Python Solutions
Solution 1 - Python
Using numpy, you can define the following:
import numpy as np
def cart2pol(x, y):
rho = np.sqrt(x**2 + y**2)
phi = np.arctan2(y, x)
return(rho, phi)
def pol2cart(rho, phi):
x = rho * np.cos(phi)
y = rho * np.sin(phi)
return(x, y)
Solution 2 - Python
The existing answers can be simplified:
from numpy import exp, abs, angle
def polar2z(r,theta):
return r * exp( 1j * theta )
def z2polar(z):
return ( abs(z), angle(z) )
Or even:
polar2z = lambda r,θ: r * exp( 1j * θ )
z2polar = lambda z: ( abs(z), angle(z) )
Note these also work on arrays!
rS, thetaS = z2polar( [z1,z2,z3] )
zS = polar2z( rS, thetaS )
Solution 3 - Python
You can use the cmath module.
If the number is converted to a complex format, then it becomes easier to just call the polar method on the number.
import cmath
input_num = complex(1, 2) # stored as 1+2j
r, phi = cmath.polar(input_num)
Solution 4 - Python
If you can't find it in numpy or scipy, here are a couple of quick functions and a point class:
import math
def rect(r, theta):
"""theta in degrees
returns tuple; (float, float); (x,y)
"""
x = r * math.cos(math.radians(theta))
y = r * math.sin(math.radians(theta))
return x,y
def polar(x, y):
"""returns r, theta(degrees)
"""
r = (x ** 2 + y ** 2) ** .5
theta = math.degrees(math.atan2(y,x))
return r, theta
class Point(object):
def __init__(self, x=None, y=None, r=None, theta=None):
"""x and y or r and theta(degrees)
"""
if x and y:
self.c_polar(x, y)
elif r and theta:
self.c_rect(r, theta)
else:
raise ValueError('Must specify x and y or r and theta')
def c_polar(self, x, y, f = polar):
self._x = x
self._y = y
self._r, self._theta = f(self._x, self._y)
self._theta_radians = math.radians(self._theta)
def c_rect(self, r, theta, f = rect):
"""theta in degrees
"""
self._r = r
self._theta = theta
self._theta_radians = math.radians(theta)
self._x, self._y = f(self._r, self._theta)
def setx(self, x):
self.c_polar(x, self._y)
def getx(self):
return self._x
x = property(fget = getx, fset = setx)
def sety(self, y):
self.c_polar(self._x, y)
def gety(self):
return self._y
y = property(fget = gety, fset = sety)
def setxy(self, x, y):
self.c_polar(x, y)
def getxy(self):
return self._x, self._y
xy = property(fget = getxy, fset = setxy)
def setr(self, r):
self.c_rect(r, self._theta)
def getr(self):
return self._r
r = property(fget = getr, fset = setr)
def settheta(self, theta):
"""theta in degrees
"""
self.c_rect(self._r, theta)
def gettheta(self):
return self._theta
theta = property(fget = gettheta, fset = settheta)
def set_r_theta(self, r, theta):
"""theta in degrees
"""
self.c_rect(r, theta)
def get_r_theta(self):
return self._r, self._theta
r_theta = property(fget = get_r_theta, fset = set_r_theta)
def __str__(self):
return '({},{})'.format(self._x, self._y)
Solution 5 - Python
There is a better way to write a method to convert from Cartesian to polar coordinates; here it is:
import numpy as np
def polar(x, y) -> tuple:
"""returns rho, theta (degrees)"""
return np.hypot(x, y), np.degrees(np.arctan2(y, x))
Solution 6 - Python
If your coordinates are stored as complex numbers you can use cmath
Solution 7 - Python
In case, like me, you're trying to control a robot that accepts a speed and heading value based off of a joystick value, use this instead (it converts the radians to degrees:
def cart2pol(x, y):
rho = np.sqrt(x**2 + y**2)
phi = np.arctan2(y, x)
return(rho, math.degrees(phi))
Solution 8 - Python
Mix of all the above answers which suits me:
import numpy as np
def pol2cart(r,theta):
'''
Parameters:
- r: float, vector amplitude
- theta: float, vector angle
Returns:
- x: float, x coord. of vector end
- y: float, y coord. of vector end
'''
z = r * np.exp(1j * theta)
x, y = z.real, z.imag
return x, y
def cart2pol(x, y):
'''
Parameters:
- x: float, x coord. of vector end
- y: float, y coord. of vector end
Returns:
- r: float, vector amplitude
- theta: float, vector angle
'''
z = x + y * 1j
r,theta = np.abs(z), np.angle(z)
return r,theta
Solution 9 - Python
Thinking about it in general, I would strongly consider hiding coordinate system behind well-designed abstraction. Quoting Uncle Bob and his book:
class Point(object)
def setCartesian(self, x, y)
def setPolar(self, rho, theta)
def getX(self)
def getY(self)
def getRho(self)
def setTheta(self)
With interface like that any user of Point class may choose convenient representation, no explicit conversions will be performed. All this ugly sines, cosines etc. will be hidden in one place. Point class. Only place where you should care which representation is used in computer memory.