我正在使用这种方法给我一个球体内的点列表。但是,当我绘制结果时,它看起来根本不是球形的。这里的逻辑肯定有问题。会是什么?
def give_sphere(x, y, z, r, num):
"""The distribution of dots in the sphere increases towards the center.
Return: A List of Points (x,y,z) which are all inside the sphere."""
points = []
for i in range(0, num):
factor = normedgauss() # A value between 0 and 1 following a gaussian
ir = r * factor
ix = x + ir * np.cos(npi())
iy = y + ir * np.sin(npi())
iz = z + ir * np.cos(npi())
points.append((ix, iy, iz))
return points
这是3D图: 我也想在3D中使用pyplot绘制点列表。我可以使用以下代码实现这一点,但是之后我无法添加另一个点云以在同一图中显示。我该怎么办?
def plot_sphere(points):
x_list = [x for [x, y, z] in points]
y_list = [y for [x, y, z] in points]
z_list = [z for [x, y, z] in points]
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(x_list, y_list, z_list)
plt.show()
答案 0 :(得分:1)
可能您正在使用均匀分布的随机数生成角度,事实并非如此。 3D中的体积差异类似于(dr^3)(d cos theta) (d phi)
,这意味着均匀分布的变量是cos theta
,而不是theta
(径向分量也一样,但我不确定您要尝试的操作,所以我保持不变)
def give_sphere(x, y, z, r, num):
points = []
for i in range(0, num):
factor = normedgauss() # A value between 0 and 1 following a gaussian
ir = r * factor
itheta = np.arccos(np.random.uniform(-1, 1))
iphi = np.random.uniform(0, 2 * np.pi)
ix = x + ir * np.sin(itheta) * np.cos(iphi)
iy = y + ir * np.sin(itheta) * np.sin(iphi)
iz = z + ir * np.cos(itheta)
points.append((ix, iy, iz))
return points
记住这一点,这就是你应该得到的
第二个问题
def plot_sphere(points, ax):
x_list = [x for [x, y, z] in points]
y_list = [y for [x, y, z] in points]
z_list = [z for [x, y, z] in points]
ax.scatter(x_list, y_list, z_list)
fig = plt.figure()
ax = Axes3D(fig)
points1 = give_sphere(0, 0, -2, 1, 1000)
points2 = give_sphere(0, 0, 2, 1, 1000)
plot_sphere(points1, ax)
plot_sphere(points2, ax)
plt.show()
答案 1 :(得分:1)
您的第一个问题是关于基于分布函数的蒙特卡洛模拟。通常,需要使用概率密度函数来推导特定的采样方案。
我假设您想在一个球体内均匀分布点。我会推荐一个最好的链接,该链接可以清楚地说明您的案件的整个过程,并鼓励您探索利弊:
Generating uniformly distributed numbers on a sphere。