Reputation: 43953
I am trying to generate points that lies on the surface of a sphere centered on (0,0) in python.
# r - the radius of the sphere
def createSphere(r):
lst = []
for z in range(-r, r+1):
r_ = r - abs(z)
if r_ == 0:
lst.append((0,0,r*np.sign(z)))
else:
for d in range(r_):
lst.append((r_ * cos(d * (360/float(r_))), r_ * sin(d * 360/float(r_))), z) )
return lst
It will return a list [(x1,y1,z1),...].
This is how the result looks like:
The surface isn't smooth, and it looks kinda like a cube with extra sharp corners.
Does anyone know whats wrong?
Thanks
Upvotes: 1
Views: 1276
Reputation: 880887
Use the standard spherical to cartesian coordinate transformation:
import math
pi = math.pi
sin = math.sin
cos = math.cos
def createSphere(r, N=10):
lst = []
thetas = [(2*pi*i)/N for i in range(N)]
phis = [(pi*i)/N for i in range(N)]
for theta in thetas:
for phi in phis:
x = r * sin(phi) * cos(theta)
y = r * sin(phi) * sin(theta)
z = r * cos(phi)
lst.append((x, y, z))
return lst
Per the comments below: If you wish to vary the number of points depending on the height (or phi
), you could let thetas
depend on phi
:
def createSphere(r, N=10):
lst = []
for phi in [(pi*i)/(N-1) for i in range(N)]:
M = int(sin(phi)*(N-1))+1
for theta in [(2*pi*i)/M for i in range(M)]:
x = r * sin(phi) * cos(theta)
y = r * sin(phi) * sin(theta)
z = r * cos(phi)
lst.append((x, y, z))
return lst
Above, the key line is
M = int(sin(phi)*(N-1))+1
M will equal 1 when phi
is 0 or pi
, and it will equal N when phi
equals pi/2
(at the "equator"). Note that this is just one possible way to define M
. Instead of using sin
, you could instead define a piecewise linear function with the same boundary values, for example...
Upvotes: 4