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 :
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:
- Move the particle drawing code over to
draw(), after thebackground()call. The will re-draw the particles on every frame, to be used for animation. - 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.