上面的代码目前生成一个立方体,而不是一个球体。我怎么能纠正这个?
x = list(range(-5,5))
y = list(range(-5,5))
z = list(range(-5,5))
r = [1,2,3,4,5,6,7,10]
xcoords = []
ycoords = []
zcoords = []
"""functions used"""
def square(number):
return number**2
"""determines which values satisfies the equation for a sphere"""
for itemx in x:
for itemy in y:
for itemz in z:
for itemr in r:
if abs(itemx) == abs(itemy) and abs(itemy) == abs(itemz) and square(itemx) + square(itemy) +square(itemz) == itemr:
xcoords.append(itemx)
ycoords.append(itemy)
zcoords.append(itemz)
"""determines the number of atoms in the system"""
natoms = len(xcoords)
"""writes coords onto txt file"""
out = open("sphere.xyz", "a")
print (natoms)
out.write("%s \n \n" %(natoms))
out.close()
for item in zip(xcoords, ycoords,zcoords):
out = open("sphere.xyz", "a")
print (item)
out.write( "Ar" " " " " "%2.5s %2.5s %2.5s \n" %(item))
out.close()
我考虑使用球面坐标来定义球体的参数,但我不知道如何使用python进行设置。
答案 0 :(得分:1)
正如我在评论中提到的,我认为你是误解情况的受害者。我的方法会有所不同 - 不要迭代固定数量的坐标并尝试点击,但只生成正确的点。我使用了众所周知的球形到笛卡尔公式,并且只为这两个角度生成了固定样本。
from __future__ import division
from math import sin, cos, pi
SAMPLES = 20
def to_x(r, theta, phi):
return r*sin(theta)*cos(phi)
def to_y(r, theta, phi):
return r*sin(theta)*sin(phi)
def to_z(r, theta, phi):
return r*cos(theta)
samples_r = [r for r in xrange(1, 10)]
samples_theta = [theta * pi / SAMPLES for theta in xrange(SAMPLES)]
samples_phi = [phi * 2*pi / SAMPLES for phi in xrange(SAMPLES)]
coords = []
for r in samples_r:
for theta in samples_theta:
for phi in samples_phi:
coords.append((to_x(r, theta, phi),
to_y(r, theta, phi),
to_z(r, theta, phi)))
for coord in coords:
out = open("sphere.xyz", "a")
print (coord)
out.write( "Ar" " " " " "%2.5s %2.5s %2.5s \n" %(coord))
out.close()
为了提高内存性能,您可以考虑使用generators和itertools模块(尤其是itertools.product似乎是针对类似问题设计的。)