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

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

4

2 回答 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 个点后概率函数的样子: 在此处输入图像描述

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

于 2013-04-06T14:29:13.060 回答
1

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

至于在我们创建人工“接缝”时计算沿表面的距离,只需同时使用 (x1-x2) 和 (w -x1+x2) - 提供较短距离的那个就是您想要的。

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

于 2013-04-06T13:02:56.750 回答