Trying to create random circle that does not overlap

Hi I’m trying to create random circles which do not overlap. I have seen a few videos on the net but they do not specifically use array to solve the question. Is there any way to do it?

Below is the code I have tried out but null pointer exception keeps showing up

PVector v1,v2;

void setup(){
  size(800,800);
  
}

void draw(){
 int circles []= new int [25]; 
   boolean overlap = false;
   for (int j =0; j < circles.length; j++){
   v2 = new PVector(random(width),random (height),50);
   float d = dist(v1.x, v1.y, v2.x, v2.y);
   if (d < v1.z + v2.z){
     overlap = true;
     break;     
 }
 if(!overlap) {
   circle(v1.x,v1.y,v1.z*2);
 }
 }
 for (int i = 0; i< circles.length; i++){
  v1 = new PVector(random(width),random (height),50);
   circle(v1.x,v1.y,v1.z*2);
   frameRate(1);
 }
}

Hi @jxjohn
I’ve not tested the sketch yet, because it is hard to copy.
Please use the pencil edit button of your post above, and copy these three ``` signs and paste them one line above your code, and one line below.
I can already see an error though. You have to place the v1 vector above v2 in draw().

Hello,

You really do need to format your code as @noel mentioned and I will second that.

https://discourse.processing.org/faq#format-your-code

I see a couple of obvious errors.

:)

Hint:
What is initial value of v1?

The other error I saw was corrected with formatting.

:)

thx i got the same output if i move v1 value after the declare array line but are there any tips to ensure that they don’t overlap.
Am i correct to say that the logic by declaring v1 before the overlapping boolean states that it does not check whether it is overlapping before drawing the circle.

I am off to work…

Some resources for you:

https://processing.org/reference/PVector.html

https://processing.org/tutorials/pvector/

https://natureofcode.com/book/chapter-1-vectors/

Experiment a little.

:)

I have experimented a little. I changed pvectors into arrays n have gotten my desired effect of one circle appear after another has been drawn, However, some circles drawn are still overlapping. @glv or @noel can u help me n see what is wrong thx.

 size(800,800);
 
}

void draw(){
float circlesx []= new float [25]; 
float circlesy []= new float [25]; 
for (int i = 0; i< 25; i++){
  circlesx[i] = random(width);
  circlesy[i] = random(height);
  boolean overlap = false;
  for (int j =0; j < circlesx.length; j++){
  circlesx[j] = random(width);
  circlesy[j] = random(height);
  float d = dist(circlesx[i], circlesy[i], circlesx[j], circlesy[j]);
  if (d < 100){
    overlap = true;
    break;     
}
if(!overlap) {
  circle(circlesx[j], circlesy[j], 50);
}
}
for (i = 0; i< 25; i++){
  circle(circlesx[i], circlesy[i], 50);
  frameRate(2);
}
}
}

I still did not copy your code because it’s missing pieces and unformatted.
Why are you using a nested ‘for’ loop? You can create a random array first, and in a second loop sort them out.

@noel what did u mean by your previous reply?

By nested I mean that one ‘for’ loop is placed –within– another ‘for’ loop.

My idea was to use nested loop to check whether the previous circle position is overlapping with the new one if it is break out of the loop and try again

If you just check overlapping one with the previous one, you still will overlap the ones before. So you have to keep track of places already used before, to not occupy them again.

@noel thx for the clarification do you have any tips to do what you just mentioned thanks.
My idea was to use the nested loops with arrays but it doesn’t seem to work

Maybe I don’t understand exactly what you want. But if the goal is to randomly draw circles on the screen that never overlap, you just write an array with a loop in setup(), setting the coordinates of the circles in a row and column so that they don’t overlap, and then display them randomly in draw() with a time-lap using frameCount %

If you want something more advanced, that doesn’t give a row/column appearance when there is a big quantity of circles displayed on the screen, you may want to use the geomerative library that can cheque if shapes overlap.

thanks what do u mean by geomerative library

Geomerative is a great library, but not very well documented. You will need some time to get a grip on it. So if you want something easier take the row/column approach, but also draw them with a none-stroke background-color, so that the row/column effect won’t be that apparent.

the slow algorithm for this is as follows.

if circles arrayList is empty add new circle.
else create new circle in random position loop all current circles and compare
if distance between new circle and current circle is greater than radius of circle 1 + radius of circle 2 then add your new circle to your circle arrayList.
repeat until you have the desired amount of circles.

Note the desired amount of circles should not exceed the amount of circles that can fit on your canvas, otherwise the last section will loop infinitely.

also whilst trying to come up with your own algorithm is a fine approach this is something which has already been sufficiently coded.

finally a poisson distribution is also an option although the packing might not be as neat or as tight. Example algorithm here. Note this is in c# but the language is pretty similar to processing.

1 Like

Well with that many code to study I’ll just add one more.

float x, y, d;
FloatList x_list = new FloatList();
FloatList y_list = new FloatList();
FloatList d_list = new FloatList();

void setup() {
  background(255);
  size(800, 800);
}

void draw() {
  boolean overlap = true;
  while (overlap == true) {
    overlap = false;
    x = random(width);
    y = random(height);
    d = random(15, 65);
    for (int i = 0; i < x_list.size(); i++) {
      float xv = x_list.get(i);
      float yv = y_list.get(i);
      float dv = d_list.get(i); 
      if (dist(xv, yv, x, y) < d/2+dv/2) { 
        overlap = true;
      }
    }
    x_list.append(x);
    y_list.append(y);
    d_list.append(d);
  }
  for (float i : x_list) {
    circle(x, y, d);
  }
}