Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

P5JS- Drawing circles that not overlapped

I have this code to draw an array of circle and make sure they will not be overalapped. I don’t know what my problem is, cause it’s not giving error but at the same time, I don’t see anything happening as well.

class particle{
  constructor(x,y,r){
    this.x=x;
    this.y=y;
    this.r=r;

  }
  
  show(){
    noFill();
    stroke(0);
    strokeWeight(1);
    ellipse(this.x,this.y,this.r);
  }
}

let circles=[];

function setup() {
  createCanvas(600, 400);
  
  for (let i=0; i<25; i++){
    let x=random(width);
    let y=random(height);
    let r=50;
    circles[i]= new particle(x,y,r);  
    
  let overlap=false;
    for (let j=0; j<circles.length; j++){
      let other=circles[j];
      let circle=circles[i];
      let d=dist( circle.x,circle.y,other.x,other.y);
      if ( d < circle.r/2 + other.r/2){
        overlap=true;
      }
      
      if (!overlap){
        circles.push(circle);
      }
    }
    circles[i].show();
  }
}

function draw() {
  background(220);
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

draw() runs ~60 times a second after setup(), which runs once. background(220); wipes the whole canvas clean, immediately overwriting the circle drawing you did in setup().

Two possible solutions, depending on whether you want an animation:

  1. Move the particle drawing code over to draw(), after the background() call. The will re-draw the particles on every frame, to be used for animation.
  2. Remove draw() entirely, and just draw the particles once.

Here’s option 2:

class Particle {
  constructor(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
  }

  show() {
    noFill();
    stroke(0);
    strokeWeight(1);
    ellipse(this.x, this.y, this.r);
  }
}

const circles = [];

function setup() {
  createCanvas(600, 400);

  for (let i = 0; i < 25; i++) {
    const x = random(width);
    const y = random(height);
    const r = 50;
    const circle = new Particle(x, y, r);
    let overlap = false;

    for (let j = 0; j < circles.length; j++) {
      const other = circles[j];
      const d = dist(circle.x, circle.y, other.x, other.y);

      if (d < circle.r / 2 + other.r / 2) {
        overlap = true;
        break;
      }
    }

    if (!overlap) {
      circles.push(circle);
      circle.show();
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>

Note that I’ve used prettier to autoformat the code and capitalized the class name, and used const instead of let when I’m not reassigning variables.

Beyond that, there are a couple issues with the overlapping logic. One issue is that circles[i] is added to the circles array and shown regardless of whether it overlaps. Also, the overlap check happens too soon–a circle should only be added after its overlap is checked against all other circles rather than inside the loop.

Another note with the overlap logic is that you might not get very many circles. If you want to guarantee you get a certain number, use a while loop and try placing another circle (or repositioning the current one) if you detect an overlap, taking care to avoid an infinite loop if there is no room for new circles to be added.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading