在框中生成随机点

问题描述 投票:0回答:1

我想在一个盒子里生成随机点(a=0.2m,b=0.2m,c=1m)。这些点之间应该有随机距离,但两点之间的最小距离应该是 0.03m,为此我使用了

random.choice
。当我运行代码时,它会生成随机点,但距离管理是错误的。另外,我的浮点转换近似值很糟糕,因为我不想更改之前生成的随机值,但我找不到任何其他解决方案。我愿意接受建议。

图片

图1 图2

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)
    
python random points packing
1个回答
1
投票

正如 @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 点。

© www.soinside.com 2019 - 2024. All rights reserved.