您的代碼生成與隨機分佈的法線的平面內。他們只是不這樣看,因爲z尺度比x尺度和y尺度大得多。
您可以通過生成平面上均勻分佈的點來生成更好看的圖像。爲此,按照 新座標(u,v)對平面進行參數化,然後在均勻間隔的網格 (u,v)點上對平面進行採樣。然後將這些(u,v)點轉換爲(x,y,z)空間中的點。
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import itertools as IT
def points_on_sphere(dim, N, norm=np.random.normal):
"""
http://en.wikipedia.org/wiki/N-sphere#Generating_random_points
"""
normal_deviates = norm(size=(N, dim))
radius = np.sqrt((normal_deviates ** 2).sum(axis=0))
points = normal_deviates/radius
return points
# Number of hyperplanes
n = 10
# Dimension of space
d = 3
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
points = points_on_sphere(n, d).T
uu, vv = np.meshgrid([-5, 5], [-5, 5], sparse=True)
colors = np.linspace(0, 1, len(points))
cmap = plt.get_cmap('jet')
for nhat, c in IT.izip(points, colors):
u = (0, 1, 0) if np.allclose(nhat, (1, 0, 0)) else np.cross(nhat, (1, 0, 0))
u /= math.sqrt((u ** 2).sum())
v = np.cross(nhat, u)
u = u[:, np.newaxis, np.newaxis]
v = v[:, np.newaxis, np.newaxis]
xx, yy, zz = u * uu + v * vv
ax.plot_surface(xx, yy, zz, alpha=0.5, color=cmap(c))
ax.set_xlim3d([-5,5])
ax.set_ylim3d([-5,5])
ax.set_zlim3d([-5,5])
plt.show()
![enter image description here](https://i.stack.imgur.com/3uZPR.png)
或者,您也可以通過使用Till Hoffmann's pathpatch_2d_to_3d utility function避免毛毛數學:
for nhat, c in IT.izip(points, colors):
p = patches.Rectangle((-2.5, -2.5), 5, 5, color=cmap(c), alpha=0.5)
ax.add_patch(p)
pathpatch_2d_to_3d(p, z=0, normal=nhat)
ax.set_xlim3d([-5,5])
ax.set_ylim3d([-5,5])
ax.set_zlim3d([-5,5])
plt.show()
![enter image description here](https://i.stack.imgur.com/cUtSs.png)
熱該死!一個真正的最小工作示例。有一個upvote。 – Veedrac 2014-10-01 19:20:51
@Veedrac你不能定義一個通過單個法線向量穿過原點的平面嗎?請參閱http://math.stackexchange.com/questions/952525/select-a-random-hyperplane。此外,我使用的方法是在http://mathworld.wolfram.com/SpherePointPicking.html – eleanora 2014-10-01 19:36:31
中的「另一種輕鬆選取隨機點[..]的方法」中描述的方法啊,你說得對兩點。傻我。 – Veedrac 2014-10-01 19:47:58