在球体上绘制点

Plotting Points on a Sphere

我正在尝试在球体上生成随机、均匀分布的点。但是,代码创建的点似乎创建了一个磁盘。我认为问题出在 "phirand" 定义中。那里的数学不正确吗?我在 Matlab 中使用了相同的代码,它在那里工作。

代码:

import numpy as np
import pylab
from scipy.integrate import odeint
import matplotlib.pyplot as plt
#import random
import mpl_toolkits.mplot3d.axes3d as p3
import random as rand

particlecount = 10 ## of particles to generate energies for energy generation
binsize = 15 #Determines bin size for historgram of electron energies
RStart = 0.02
phi1 = 0
phi2 = 180
phi1rad = phi1*(np.pi/180)
phi2rad = phi2*(np.pi/180)

#Generate random positions for each particle between s1 and s2
ICPositions = np.array([])
for i in range(0,particlecount):
    #In Spherical: Generates random position with boundaries of: S1<r<S2
    thetarand = (2*np.pi)*rand.uniform(0,1) #Random # generation for component y between s1 and s2
    phirand = np.arcsin((np.sin(phi2rad) - np.sin(phi1rad))*rand.uniform(0,1) + np.sin(phi1rad))
    xrand = RStart*np.sin(phirand)*np.cos(thetarand)
    yrand = RStart*np.sin(phirand)*np.sin(thetarand)
    zrand = RStart*np.cos(phirand)
    randArray = np.array([xrand,yrand,zrand])
    randArray = np.array(randArray,dtype = float)
    if ICPositions.size == 0:
        ICPositions = np.array([randArray])
    else:
        ICPositions = np.append(ICPositions,[randArray],axis = 0)

print(ICPositions)

fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.scatter(ICPositions[:,0],ICPositions[:,1],ICPositions[:,2],c='r',marker='o')
ax.set_xlabel('x axis')
ax.set_ylabel('y axis')
ax.set_zlabel('z axis')
plt.show()

我找到了解决方案,但不明白它为什么有效。从数学上讲,我对 x、y 和 z 的转换定义没有任何问题(在我用谷歌搜索并查阅教科书之后)。但是,我看到另一个 post,其中有人对这些坐标的定义略有不同(将所有 phi 分量的正弦替换为余弦),但没有解释原因。当我替换它时,以下工作正常:

xrand = RStart*np.sin(phirand)*np.cos(thetarand)
yrand = RStart*np.sin(phirand)*np.sin(thetarand)
zrand = RStart*np.cos(phirand)

有了这个:

xrand = RStart*np.cos(phirand)*np.cos(thetarand)
yrand = RStart*np.cos(phirand)*np.sin(thetarand)
zrand = RStart*np.sin(phirand)

同样,我不知道为什么会这样,但@Jenny 对另一个 post 提出了关于同一代码的不同问题的提示。使用 [-90,90] 而不是 [0,180] 可能是需要进行此更改的原因,但我再次不确定为什么 sin[0,90,180] --> [0,1,0] 而 cos[-90,0 ,90] --> [0,1,0] 并且都涵盖相同的数值范围。如果有人对此有充分的 mathematical/coding 理由,请评论我的回答以进一步解释。