在圆柱体表面生成随机点

5
我希望您能在圆柱体表面生成随机点,以使点之间的距离在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

我应该如何生成随机点,使它们在柱体表面范围内落下?


沿圆柱体表面的距离,还是直线(欧几里得)? - NPE
1
请将此添加到问题中。 - NPE
我同意@Robᵩ的观点 - 在给定的限制条件下,表面上的最大点数为三,仅当第一个点靠近圆柱体的底部/顶部时,其他情况下只能容纳两个点。@user1407199:为什么在r = math.sqrt(s)*R中检索随机数的平方根? - furins
抱歉没有表达清楚, - user1407199
2
我相信你正在寻找的是Poisson disc sampling - Vincent Nivoliers
显示剩余8条评论
2个回答

1
创建一组具有位置约束的随机点的基本方法是使用一个函数来调制放置点的概率,使其能够在指定位置上。该函数最初是常数,每当放置一个点时,禁止点周围的区域就被设置为零。如果您将问题离散化,则很难处理连续变量,但相对容易处理。
另一个需要注意的问题是如何在圆柱体上进行操作。将其视为在矩形区域上随机放置点,并且该矩形区域会周期性地重复出现可能更容易。这可以通过以下两种不同的方式来处理:
1. 最简单的方法是考虑不仅将点放置在主要矩形中,还要将其放置在相邻的矩形中,并计算它们对主矩形内的概率函数的影响。 2. 更复杂的方法是将概率函数视为编码禁止区域的卷积核,与已放置的点对应的delta函数之和。如果使用FFT计算,则周期性是自然产生的。
第一种方法可以按如下方式编码:
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 请注意,这些点作为坐标对返回,第一个是高度,第二个是沿圆柱体周长的距离。

1
这不是一个完整的解决方案,而是一种有助于解决问题的见解。如果你将圆柱体的表面“展开”成高度为h、宽度为w=2*pi*r的矩形,那么寻找点之间距离的任务就变得简单了。你没有解释如何测量圆柱体顶部和侧面之间的“沿表面距离”,这是一个稍微棘手的几何问题。
至于在我们创建人工“接缝”时计算沿表面距离,只需使用(x1-x2)和(w-x1+x2)中较短的距离即可。
我认为@VincentNivoliers建议使用泊松盘采样非常好,但在h=300和r=20的限制下,无论做什么都会得到糟糕的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接