[英]Points on sphere
我是Python的新手,我有一個半徑(R)的球面,並以(x0,y0,z0)為中心。 現在,我需要找到那些在球體表面或球體內的點,例如滿足((x1-x0)** 2+(y1-y0)** 2的點(x1,y1,z1) +(z1-x0)* 82)** 1/2 <=R。我只想以numpy數組的形式打印這些點的坐標。 輸出將是這樣的-[[x11,y11,z11],[x12,y12,z12],...]。 到目前為止,我有以下代碼-
import numpy as np
import math
def create_points_around_atom(number,atom_coordinates):
n= number
x0 = atom_coordinates[0]
y0 = atom_coordinates[1]
z0 = atom_coordinates[2]
R = 1.2
for i in range(n):
phi = np.random.uniform(0,2*np.pi,size=(n,))
costheta = np.random.uniform(-1,1,size=(n,))
u = np.random.uniform(0,1,size=(n,))
theta = np.arccos(costheta)
r = R * np.cbrt(u)
x1 = r*np.sin(theta)*np.cos(phi)
y1 = r*np.sin(theta)*np.sin(phi)
z1 = r*np.cos(theta)
dist = np.sqrt((x1-x0)**2+(y1-y0)**2+(z1-z0)**2)
distance = list(dist)
point_on_inside_sphere = []
for j in distance:
if j <= R:
point_on_inside_sphere.append(j)
print('j:',j,'\tR:',R)
print('The list is:', point_on_inside_sphere)
print(len(point_on_inside_sphere))
kk =0
for kk in range(len(point_on_inside_sphere)):
for jj in point_on_inside_sphere:
xx = np.sqrt(jj**2-y1**2-z1**2)
yy = np.sqrt(jj**2-x1**2-z1**2)
zz = np.sqrt(jj**2-y1**2-x1**2)
print("x:", xx, "y:", yy,"z:", zz)
kk +=1
我正在運行它create_points_around_atom(n=2,structure[1].coords)
,其中structure[1].coords
是一個由三個坐標組成的numpy數組。
總結評論中討論的內容以及其他一些要點:
不需要過濾點,因為u <= 1
,這意味着np.cbrt(u) <= 1
,因此r = R * np.cbrt(u) <= R
,即所有點都已經在內部或內部球體的表面。
調用size=(n,)
np.random.uniform
會創建一個由n
元素組成的數組,因此無需循環執行n
次。
您正在過濾atom_coordinate
距離,但是生成的點以[0, 0, 0]
為中心,因為您沒有添加此偏移量。
將R
作為參數傳遞似乎比對它進行硬編碼更為明智。
無需像在C語言中有時那樣“預加載” Python中的參數。
由於sin(theta)
在球面上是非負的,因此您可以使用costheta
cos²(x) + sin²(x) = 1
從costheta
數組直接計算出它。
示例實施:
# pass radius as an argument
def create_points_around_atom(number, center, radius):
# generate the random quantities
phi = np.random.uniform( 0, 2*np.pi, size=(number,))
theta_cos = np.random.uniform(-1, 1, size=(number,))
u = np.random.uniform( 0, 1, size=(number,))
# calculate sin(theta) from cos(theta)
theta_sin = np.sqrt(1 - theta_cos**2)
r = radius * np.cbrt(u)
# use list comprehension to generate the coordinate array without a loop
# don't forget to offset by the atom's position (center)
return np.array([
np.array([
center[0] + r[i] * theta_sin[i] * np.cos(phi[i]),
center[1] + r[i] * theta_sin[i] * np.sin(phi[i]),
center[2] + r[i] * theta_cos[i]
]) for i in range(number)
])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.