在圆柱体表面上生成随机点

时间:2013-04-04 12:23:45

标签: python

我想在圆柱表面上生成随机点,使得点之间的距离落在230和250的范围内。我使用以下代码在圆柱面上生成随机点:

import random,math
H=300
R=20
s=random.random()
#theta = random.random()*2*math.pi
for i in range(0,300):
    theta = random.random()*2*math.pi
    z = random.random()*H
    r=math.sqrt(s)*R
    x=r*math.cos(theta)
    y=r*math.sin(theta)
    z=z
    print 'C'  , x,y,z

如何生成随机点,使它们落在范围内(在圆柱面上)?

2 个答案:

答案 0 :(得分:1)

这不是一个完整的解决方案,而是一个应该有所帮助的见解。如果您将圆柱体的表面“展开”为宽度为w=2*pi*r且高度为h的矩形,则可以简化查找点之间距离的任务。你还没有解释如何测量圆柱体顶部和侧面之间的“沿表面的距离” - 这是一个稍微有点棘手的几何形状。

至于计算创建人工“缝”时沿表面的距离,只需使用(x1-x2)和(w-x1 + x2) - 无论哪个都给出了你想要的距离越短。

我认为@VincentNivoliers建议使用Poisson磁盘采样是非常好的,但是在h = 300和r = 20的约束下,无论如何都会得到可怕的结果。

答案 1 :(得分:1)

在它们之间的位置创建一组具有约束的随机点的基本方法是具有调制点被放置在特定位置的概率的函数。此函数从一个常量开始,无论何时放置一个点,该点周围的禁区都设置为零。连续变量很难做到这一点,但如果你将问题自行化,则相当容易。

要注意的另一件事是在圆柱部分上。可能更容易将其视为矩形区域上的随机点,其周期性地重复。这可以通过两种不同的方式处理:

  1. 最简单的方法是不仅要考虑放置点的矩形瓦片,还要考虑其相邻的矩形瓦片。每当您在主要图块中放置一个点时,您也会在相邻图块中放置一个点并计算其对图块内概率函数的影响。

  2. 更复杂的方法考虑概率函数,然后对编码禁止区域的内核进行卷积,并使用delta函数的总和,对应于已经放置的点。如果这是使用FFT计算的,则周期性是按产品解释的。

  3. 第一种方法可编码如下:

    from __future__ import division
    import numpy as np
    
    r, h = 20, 300
    w = 2*np.pi*r
    int_w = int(np.rint(w))
    mult = 10
    pdf = np.ones((h*mult, int_w*mult), np.bool)
    points = []
    min_d, max_d = 230, 250
    
    available_locs = pdf.sum()
    while available_locs:
        new_idx = np.random.randint(available_locs)
        new_idx = np.nonzero(pdf.ravel())[0][new_idx]
        new_point = np.array(np.unravel_index(new_idx, pdf.shape))
        points += [new_point]
        min_mask = np.ones_like(pdf)
        if max_d is not None:
            max_mask = np.zeros_like(pdf)
        else:
            max_mask = True
        for p in [new_point - [0, int_w*mult], new_point +[0, int_w*mult],
                  new_point]:
            rows = ((np.arange(pdf.shape[0]) - p[0]) / mult)**2
            cols = ((np.arange(pdf.shape[1]) - p[1]) * 2*np.pi*r/int_w/mult)**2
            dist2 = rows[:, None] + cols[None, :]
            min_mask &= dist2 > min_d*min_d
            if max_d is not None:
                max_mask |= dist2 < max_d*max_d
        pdf &= min_mask & max_mask
        available_locs = pdf.sum()
    points = np.array(points) / [mult, mult*int_w/(2*np.pi*r)]
    

    如果使用您的值运行它,输出通常只有一个或两个点,因为较大的最小距离禁止所有其他值。但如果你用更合理的价值运行它,例如

    min_d, max_d = 50, 200
    

    以下是放置前5个点后概率函数的外观: enter image description here

    请注意,这些点以坐标对的形式返回,第一个是高度,第二个是沿圆柱周长的距离。