创建一组在它们之间的位置上具有约束条件的随机点的基本方法是使用一个函数来调节点放置在某个位置的概率。这个函数一开始是一个常数,每当放置一个点时,该点周围的禁止区域都会设置为零。这对于连续变量来说很难做到,但如果你离散化你的问题,那就相当容易了。
要注意的另一件事是位于圆柱体部分。将其视为周期性重复的矩形区域上的随机点可能更容易。这可以通过两种不同的方式处理:
最简单的方法是不仅要考虑放置点的矩形瓷砖,还要考虑其相邻的瓷砖。每当您在主图块中放置一个点时,您也会在相邻的点中放置一个点,并计算它们对图块内概率函数的影响。
一种更复杂的方法考虑概率函数,然后考虑对禁止区域进行编码的内核的卷积,以及与已放置的点相对应的 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 个点后概率函数的样子:
请注意,这些点以坐标对的形式返回,第一个是高度,第二个是沿圆柱圆周的距离。