答案 0 :(得分:6)
最后我设法得到了结果。
生成具有蓝色噪声属性的点分布的一种方法 是通过Poisson-Disk分布
遵循快速泊松磁盘采样中的算法 任意尺寸,Robert Bridson 我有:
论文中提到的步骤是:
步骤0.初始化用于存储的n维背景网格 样本和加速空间搜索。我们选择细胞大小 由r / sqrt(n)限定,以便每个网格单元最多包含一个 样本,因此网格可以实现为简单的n维 整数数组:默认值-1表示没有样本,非负数 integer给出位于单元格中的样本的索引
步骤1.选择从中均匀随机选择的初始样本x0 域名。将其插入背景网格,并初始化 带有此索引(零)的“活动列表”(样本索引数组)。
步骤2.当活动列表不为空时,从中选择随机索引 它(说我)。生成从中均匀选择的k个点 在xi周围的半径r和2r之间的球形环。对于每个点 转,检查它是否在现有样品的距离r内(使用 背景网格只测试附近的样本)。如果一个点是充分的 远离现有样本,将其作为下一个样本发出并添加到其中 活动列表。如果在k次尝试之后没有找到这样的点,而是 从活动列表中删除i。
请注意,为简单起见,我跳过了第0步。尽管运行时仍然合理。它是< ,5S。实施此步骤肯定会提高性能。
以下是Processing中的示例代码。它是一种基于Java构建的语言,因此语法非常相似。为您的目的翻译它应该不难。
import java.util.List;
import java.util.Collections;
List<PVector> poisson_disk_sampling(int k, int r, int size)
{
List<PVector> samples = new ArrayList<PVector>();
List<PVector> active_list = new ArrayList<PVector>();
active_list.add(new PVector(random(size), random(size)));
int len;
while ((len = active_list.size()) > 0) {
// picks random index uniformly at random from the active list
int index = int(random(len));
Collections.swap(active_list, len-1, index);
PVector sample = active_list.get(len-1);
boolean found = false;
for (int i = 0; i < k; ++i) {
// generates a point uniformly at random in the sample's
// disk situated at a distance from r to 2*r
float angle = 2*PI*random(1);
float radius = random(r) + r;
PVector dv = new PVector(radius*cos(angle), radius*sin(angle));
PVector new_sample = dv.add(sample);
boolean ok = true;
for (int j = 0; j < samples.size(); ++j) {
if (dist(new_sample.x, new_sample.y,
samples.get(j).x, samples.get(j).y) <= r)
{
ok = false;
break;
}
}
if (ok) {
if (0 <= new_sample.x && new_sample.x < size &&
0 <= new_sample.y && new_sample.y < size)
{
samples.add(new_sample);
active_list.add(new_sample);
len++;
found = true;
}
}
}
if (!found)
active_list.remove(active_list.size()-1);
}
return samples;
}
List<PVector> samples;
void setup() {
int SIZE = 500;
size(500, 500);
background(255);
strokeWeight(4);
noLoop();
samples = poisson_disk_sampling(30, 10, SIZE);
}
void draw() {
for (PVector sample : samples)
point(sample.x, sample.y);
}
但是,它需要为无限平面工作。
您可以使用参数size
控制框的大小。 r
控制点之间的相对距离。 k
控制在拒绝当前之前应尝试的新样本数量。该文件建议k=30
。