我想在一个盒子里生成随机点(a=0.2m,b=0.2m,c=1m)。这些点之间应该有随机距离,但两点之间的最小距离应该是 0.03m,为此我使用了
random.choice
。当我运行代码时,它会生成随机点,但距离管理是错误的。另外,我的浮点转换近似值很糟糕,因为我不想更改之前生成的随机值,但我找不到任何其他解决方案。我愿意接受建议。
图片
import random
import matplotlib.pyplot as plt
# BOX a = 0.2m b=0.2m h=1m
save = 0 #for saving 3 different plot.
for k in range(3):
pointsX = [] #information of x coordinates of points
pointsY = [] #information of y coordinates of points
pointsZ = [] #information of z coordinates of points
for i in range(100): #number of the points
a = random.uniform(0.0,0.00001) #for the numbers generated below are float.
x = random.choice(range(3, 21,3)) #random coordinates for x
x1 = x/100 + a
pointsX.append(x1)
y = random.choice(range(3, 21,3)) #random coordinates for y
y1 = y/100 + a
pointsY.append(y1)
z = random.choice(range(3, 98,3)) #random coordinates for z
z1 = z/100 + a
pointsZ.append(z1)
new_pointsX = list(set(pointsX)) # deleting if there is a duplicates
new_pointsY = list(set(pointsY))
new_pointsZ = list(set(pointsZ))
# i wonder max and min values it is or not between borders.
print("X-Min", min(new_pointsX))
print("X-Max", max(new_pointsX))
print("Y-Min", min(new_pointsY))
print("Y-Max", max(new_pointsY))
print("Z-Min", min(new_pointsZ))
print("Z-Max", max(new_pointsZ))
if max(new_pointsX) >= 0.2 or max(new_pointsY) >= 0.2:
print("MAX VALUE GREATER THAN 0.2")
if max(new_pointsZ) >= 0.97:
print("MAX VALUE GREATER THAN 0.97")
#3D graph
fig = plt.figure(figsize=(18,9))
ax = plt.axes(projection='3d')
ax.set_xlim([0, 0.2])
ax.set_ylim([0, 0.2])
ax.set_zlim([0, 1])
ax.set_title('title',fontsize=18)
ax.set_xlabel('X',fontsize=14)
ax.set_ylabel('Y',fontsize=14)
ax.set_zlabel('Z',fontsize=14)
ax.scatter3D(new_pointsX, new_pointsY, new_pointsZ);
save += 1
plt.savefig("graph" + str(save) + ".png", dpi=900)
正如 @user3431635 的评论中提到的,您可以在将新点添加到列表之前检查每个点与所有先前的点。我会这样做:
import random
import numpy as np
import matplotlib.pyplot as plt
plt.close("all")
a = 0.2 # x bound
b = 0.2 # y bound
c = 1.0 # z bound
dmin = 0.03 # minimum L2-norm distance
N = 1000 # number of points
def distance(p, points, min_distance):
"""
Determines if any points in the list are less than the minimum specified
distance apart.
Parameters
----------
p : tuple
`(x,y,z)` point.
points : ndarray
Array of points to check against. `x, y, z` points are columnwise.
min_distance : float
Minimum allowable distance between any two points.
Returns
-------
bool
True if point `p` is at least `min_distance` from all points in `points`.
"""
# L2-norm distance
distances = np.linalg.norm(p - points, axis=1, ord=2)
return np.all(distances >= min_distance)
x_choices = np.linspace(0, a, 100000)
y_choices = np.linspace(0, b, 100000)
z_choices = np.linspace(0, c, 100000)
points = np.array([]) # x, y, z columnwise
while points.shape[0] < 1000:
x = random.choice(x_choices)
y = random.choice(y_choices)
z = random.choice(z_choices)
p = (x,y,z)
# add first point blindly
if len(points) == 0:
points = np.array([p])
# ensure the minimum distance is met
elif distance(p, points, dmin):
points = np.vstack((points, p))
fig = plt.figure(figsize=(18,9))
ax = plt.axes(projection='3d')
ax.set_xlim([0, a])
ax.set_ylim([0, b])
ax.set_zlim([0, c])
ax.set_title('title',fontsize=18)
ax.set_xlabel('X',fontsize=14)
ax.set_ylabel('Y',fontsize=14)
ax.set_zlabel('Z',fontsize=14)
ax.scatter(points[:,0], points[:,1], points[:,2])
请注意,这可能不是您正在寻找的随机性。我已经编写了它来获取 x、y 和 z 值的范围并将其分成 100000 个增量;然后从这些值中选择一个新的 x、y 或 z 点。