无限蓝噪声

时间:2015-10-06 20:44:51

标签: algorithm point infinite noise

我正在寻找一种能产生类似于蓝噪声的点位置结果的算法。

enter image description here

但是,它需要为无限平面工作。给出边界框的地方,它返回所有内部点的位置。任何帮助,将不胜感激。我做了很多研究,发现没有什么能满足我的需求。

1 个答案:

答案 0 :(得分:6)

最后我设法得到了结果。

  

生成具有蓝色噪声属性的点分布的一种方法   是通过Poisson-Disk分布

遵循快速泊松磁盘采样中的算法 任意尺寸,Robert Bridson 我有:

enter image description here

论文中提到的步骤是:

  

步骤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