# Poisson-disc Sampling

**URL:** <https://discourse.processing.org/t/poisson-disc-sampling/14869>\
**Category:** Coding Questions\
**Created:** [October 22, 2019, 11:44am UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869 "2019-10-22T11:44:18Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [October 22, 2019, 11:44am UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/1 "2019-10-22T11:44:19Z")

</div>

Hi there,

I’ve been working from one of Daniel Shiffman’s coding challenges and have been trying to implement it from P5.js to Processing.

Im almost there but I always get an Array Index Out Of Bounds error (line 68).

The code is not pretty and Im sure I’ve made some rookie errors.

I’d appreciate if someone could glance over this for me and steer me in the right direction.

cheers

```auto
float r = 15;                 
int k = 30; //limit of samples
PVector [] grid;
float cellSize = r / sqrt(2); 
int cols;
int rows;
ArrayList <PVector> active; //active list
ArrayList <PVector> ordered;

void setup() {
  size (400,400);
  background(0);

//STEP 0 - setup grid
  cols = floor(width/cellSize);
  rows = int(height/cellSize);
  grid = new PVector[cols * rows];
  
  active = new ArrayList<PVector>();
  ordered = new ArrayList<PVector>();
  for (int i = 0; i < cols * rows; i ++) {
    grid[i] = null;
  }

//STEP 1 - pick a random point to start
  float x = random(width); // choose random x on canvas...
  float y = random(height); // choose random y on canvas...
  int i = floor(x / cellSize); // grid "x" position
  int j = floor(y / cellSize); // grid "y" position
  PVector pos = new PVector(x,y); // make position vector
  grid[i + j * cols] = pos; // insert into grid
  active.add(pos);
}

void draw () {
  background(0);

  //STEP 2
  if(active.size() > 0) { // as long as active is not empty
    int randIndex = floor(random(active.size()));
    PVector pos = active.get(randIndex);
    boolean found = false;

    for(int n = 0; n < k; n ++) { // generate up to k sample points

      PVector sample = PVector.random2D(); // use a random vector
      float magnitude = random(r,2*r);
      sample.setMag(magnitude);
      sample.add(pos);

      int colX = floor(sample.x/cellSize); // x position in grid
      int colY = floor(sample.y/cellSize); // y position in grid

      if (colX >= 1 &&
          colY >= 1 &&
          colX <= cols -1 &&
          colY <= rows -1 &&
          grid[colX + colY * cols] == null) {

            boolean ok = true;
            for(int i = -1; i <= 1; i ++) {
              for(int j = -1; j <= 1; j ++) {
                int index = (colX + i) + (colY + j) * cols;
                //println(index);
                PVector neighbor = grid[index];
                if (neighbor != null) { //is valid
                    float d = PVector.dist(sample,neighbor);
                    if (d < r) {
                      ok = false;
                  }
              }
          }
      }
      if(ok) {
        found = true;
        grid[colX + colY * cols] = sample;
        active.add(sample);
        ordered.add(sample);
        break;
      }
    }
    }
    if(!found) {
      active.remove(randIndex);
    }
  }

  for(int i = 0; i < grid.length; i ++) {
    if(grid[i] != null){
      stroke (255);
      strokeWeight(4);
      point(grid[i].x,grid[i].y);
    }
  }

  for(int i = 0; i < active.size(); i ++) {  
      stroke (255,0,255);
      strokeWeight(4);
      point(active.get(i).x,active.get(i).y);  
  }
}

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [October 22, 2019, 12:02pm UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/2 "2019-10-22T12:02:52Z")

</div>

just to get it running ( without reading or understanding it )

```auto
            if ( index > grid.length-1 ) index = grid.length-1;

```

---

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [October 23, 2019, 9:37am UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/3 "2019-10-23T09:37:41Z")

</div>

@kllThanks for your reply.  
This didn’t help unfortunately. I do have an if statement with some conditions that should help avoid the error.

It does run, but eventually I always get the out of bounds exception. I can’t figure out why though.

---

<div class="post-metadata">

**Author:** ![Tiemen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tiemen/32/5477_2.png) [@Tiemen](https://discourse.processing.org/u/Tiemen)\
**Post date:** [October 23, 2019, 9:49am UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/4 "2019-10-23T09:49:35Z")

</div>

Hi there TimoL,

The reason for the `ArrayIndexOutOfBoundsException` error is because you’re asking for data that’s not there. Add the following line of code at the bottom of `void setup()`:

```auto
println(i + " * " + j + " * " + cols + " = " + grid.length);

```

Combining this with the error feedback, do you understand what’s causing the issue?

---

<div class="post-metadata">

**Author:** ![Waboqueox](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/waboqueox/32/5643_2.png) [@Waboqueox](https://discourse.processing.org/u/Waboqueox)\
**Post date:** [October 23, 2019, 9:53am UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/5 "2019-10-23T09:53:52Z")

</div>

Yep, just control your indexes 😛

> **Spoiler**
>
> ```auto
> if (index < grid.length){
> 
> ```
> 
> > **Final Spoiler**
> >
> > ```
> > PVector neighbor = grid[index];
> > if (neighbor != null) { //is valid
> > float d = PVector.dist(sample,neighbor);
> > if (d < r) {
> > ok = false;
> > 
> > ```
> 
> ```auto
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [October 23, 2019, 2:47pm UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/6 "2019-10-23T14:47:19Z")

</div>

Appreciate the help fellas. 🙂

But I’m still getting the error.  
I understand why its happening; my grid array only goes up to a certain size and and what’s happening is a number above that is being called.

But from what I can see the if statement (line 57) should guard against that. I feel like the answer is staring me in the face.

I’ll continue to stare back until it hits me or one of you kind souls can help.  
Cheers!

---

<div class="post-metadata">

**Author:** ![Tiemen](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tiemen/32/5477_2.png) [@Tiemen](https://discourse.processing.org/u/Tiemen)\
**Post date:** [October 23, 2019, 9:46pm UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/7 "2019-10-23T21:46:41Z")

</div>

You use the if statements as measurement, but have you taken in account that you subsequently increasing these numbers again in the nested for-loops that follow?

```auto
for(int i = -1; i <= 1; i ++) {
   for(int j = -1; j <= 1; j ++) {
      int index = (colX + i) + (colY + j) * cols;

```

I ran your sketch several times, and each time the error pops up when `(colY + j)` equals 37 (because j = 1 at that point).

---

<div class="post-metadata">

**Author:** ![Waboqueox](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/waboqueox/32/5643_2.png) [@Waboqueox](https://discourse.processing.org/u/Waboqueox)\
**Post date:** [October 24, 2019, 7:46am UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/8 "2019-10-24T07:46:54Z")

</div>

> [@TimoL](#):
>
> But I’m still getting the error.

Sorry, I don’t know then what is happening 🤯 … running your code with the fixed indexes like 10 times (🤪) I didn’t get any error …

> **This code doesn't give me any error**
>
> ```float
> int k = 30; //limit of samples
> PVector [] grid;
> float cellSize = r / sqrt(2); 
> int cols;
> int rows;
> ArrayList <PVector> active; //active list
> ArrayList <PVector> ordered;
> 
> void setup() {
> size (400,400);
> background(0);
> 
> //STEP 0 - setup grid
> cols = floor(width/cellSize);
> rows = int(height/cellSize);
> grid = new PVector[cols * rows];
>   
> active = new ArrayList<PVector>();
> ordered = new ArrayList<PVector>();
> for (int i = 0; i < cols * rows; i ++) {
> grid[i] = null;
> }
> 
> //STEP 1 - pick a random point to start
> float x = random(width); // choose random x on canvas...
> float y = random(height); // choose random y on canvas...
> int i = floor(x / cellSize); // grid "x" position
> int j = floor(y / cellSize); // grid "y" position
> PVector pos = new PVector(x,y); // make position vector
> grid[i + j * cols] = pos; // insert into grid
> active.add(pos);
> }
> 
> void draw () {
> background(0);
> 
> //STEP 2
> if(active.size() > 0) { // as long as active is not empty
> int randIndex = floor(random(active.size()));
> PVector pos = active.get(randIndex);
> boolean found = false;
> 
> for(int n = 0; n < k; n ++) { // generate up to k sample points
> 
> PVector sample = PVector.random2D(); // use a random vector
> float magnitude = random(r,2*r);
> sample.setMag(magnitude);
> sample.add(pos);
> 
> int colX = floor(sample.x/cellSize); // x position in grid
> int colY = floor(sample.y/cellSize); // y position in grid
> 
> if (colX >= 1 &&
> colY >= 1 &&
> colX <= cols -1 &&
> colY <= rows -1 &&
> grid[colX + colY * cols] == null) {
> 
> boolean ok = true;
> for(int i = -1; i <= 1; i ++) {
> for(int j = -1; j <= 1; j ++) {
> int index = (colX + i) + (colY + j) * cols;
> //println(index);
> if (index < grid.length){
> PVector neighbor = grid[index];
> if (neighbor != null) { //is valid
> float d = PVector.dist(sample,neighbor);
> if (d < r) {
> ok = false;
> }
> }}
> }
> }
> if(ok) {
> found = true;
> grid[colX + colY * cols] = sample;
> active.add(sample);
> ordered.add(sample);
> break;
> }
> }
> }
> if(!found) {
> active.remove(randIndex);
> }
> }
> 
> for(int i = 0; i < grid.length; i ++) {
> if(grid[i] != null){
> stroke (255);
> strokeWeight(4);
> point(grid[i].x,grid[i].y);
> }
> }
> 
> for(int i = 0; i < active.size(); i ++) {  
> stroke (255,0,255);
> strokeWeight(4);
> point(active.get(i).x,active.get(i).y);  
> }
> }
> 
> ```

Other thing is that you want to care about your indexes carefully and don’t want to use the if condition, then… okay you have to figure out other elegant way 😛, but I didn’t understood the question 😅

Regards 👋

---

<div class="post-metadata">

**Author:** ![TimoL](https://avatars.discourse-cdn.com/v4/letter/t/9fc29f/32.png) [@TimoL](https://discourse.processing.org/u/TimoL)\
**Post date:** [October 28, 2019, 1:28pm UTC](https://discourse.processing.org/t/poisson-disc-sampling/14869/9 "2019-10-28T13:28:12Z")

</div>

Thanks for all the help guys. I’ve cleaned up my code and after comparing it to yours can see where I went wrong.

cheers 🙂
