Endless blue noise

I am looking for an algorithm that produces a dot placement result similar to blue noise.

enter image description here

However, it should work for an infinite plane. Where the bounding box is specified, and it returns the locations of all the points that fall inside. Any help would be greatly appreciated. I did a lot of research and did not find anything that would suit my needs.

+4
source share
1 answer

Finally, I managed to get the results.

One way to generate point distributions with a blue noise property using a Poisson disk distribution

, :

enter image description here

:

0. n- . r/sqrt (n), , , , n- : -1 , integer ,

1. x0, . " " ( ) ().

2. , (, i). k , r 2r xi. , , r ( , ). , . k , .

, 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.

+5

Source: https://habr.com/ru/post/1610498/


All Articles