-1

I am trying the simple circle filling and it works. But when I try to fill the first circle with more circles, it hangs the program immediately. Here's my draw and and class code which fills the circles inside circles:

let krr=[];

function draw() {
  background(0);
  print(cir.length,krr.length)
  if (cir.length<=100){
    let temp=new c();
    cir.push(temp);
    }
  else if (krr.length<100){
    print(1)
    fr=cir[0]
      if (fr.r>50){
        let re=new cirgain(fr.x,fr.y,(fr.r)/2)
        krr.push(re);
        }
  }
  for (let h of krr){
    h.show();
  }
  
  for (let g of cir){
    g.show();
    g.grow();
    
  }  
  
}
class cirgain{
  constructor(x,y,r){
    this.smr=floor(r/3);
    if (krr.length==0){
      while (true){
        this.x=random(x-r+1,x+r-1);
        this.y=random(y-r+1,y+r-1)
        if (this.x*this.x+this.y*this.y<r*r-2){
          break
          }
      }
    }
    else{
      let flag1=1
      let count1=0
      while (flag){
        if (count1>=500){
          count1=0;
          this.smr--;
        }
        while (true){
          this.x=random(x-r+1,x+r-1);
          this.y=random(y-r+1,y+r-1);
          if (this.x*this.x+this.y*this.y<r*r-2)
            break
        }
        for (let i=0;i<krr.length;i++){
          if (dist(krr[i].x,krr[i].y,this.x,this.y)<r+this.smr){
            flag1=1
            count1++;
            break;
          }
          flag1=0;
        }
      }
      
    }
    this.ccc=createVector(random(255),random(100,255),random(100,255))
  
  }
  
  show(){
    stroke(0);
    noFill();
    strokeWeight(3)
    stroke(this.ccc.x,this.ccc.y,this.ccc.z);
    circle(this.x,this.y,this.smr)
  }
}

If the whole code (including setup and class c (which at first fills the space with circles)) is needed, let me know, I will edit to include it.

Edit: Okay, here is the whole code:

let cir = [];
let maxR;
let krr = [];

function setup() {
  createCanvas(windowWidth, windowHeight);
  maxR = width / 4;
  if (height > width)
    maxR = height / 4
  colorMode(HSB);
  angleMode(DEGREES);
}

function draw() {
  background(0);
  print(cir.length, krr.length)
  if (cir.length <= 100) {
    let temp = new c();
    cir.push(temp);
  } else if (krr.length < 100) {
    print(1)
    fr = cir[0]
    if (fr.r > 50) {
      let re = new cirgain(fr.x, fr.y, (fr.r) / 2)
      krr.push(re);
    }
  }
  for (let h of krr) {
    h.show();
  }

  for (let g of cir) {
    g.show();
    g.grow();

  }

}
class c {
  constructor() {
    this.tempr = 1
    if (cir.length == 0) {
      this.x = random(maxR + 1, width - maxR - 1);
      this.y = random(maxR + 1, height - maxR - 1)
      this.r = maxR;
    } else {
      let flag = 1
      let count = 0
      while (flag) {
        if (count >= 500) {
          count = 0;
          maxR--;
        }
        this.x = random(maxR / 2 + 1, width - maxR / 2 - 1);
        this.y = random(maxR / 2 + 1, height - maxR / 2 - 1);
        this.r = maxR;
        for (let i = 0; i < cir.length; i++) {
          if (dist(cir[i].x, cir[i].y, this.x, this.y) < cir[i].r / 2 + this.r / 2 + 3) {
            flag = 1
            count++;
            break;
          }
          flag = 0;
        }
      }

    }
    this.cc = createVector(random(255), random(100, 255), random(100, 255))

  }

  show() {
    stroke(0);
    noFill();
    strokeWeight(3)
    stroke(this.cc.x, this.cc.y, this.cc.z);
    circle(this.x, this.y, this.tempr)
    rectMode(CENTER);
  }
  grow() {
    if (this.tempr <= this.r)
      // this.tempr+=.5
      this.tempr += this.r / 100
  }


}


class cirgain {
  constructor(x, y, r) {
    this.smr = floor(r / 3);
    if (krr.length == 0) {
      while (true) {
        this.x = random(x - r + 1, x + r - 1);
        this.y = random(y - r + 1, y + r - 1)
        if (this.x * this.x + this.y * this.y < r * r - 2) {
          break
        }
      }
    } else {
      let flag1 = 1
      let count1 = 0
      while (flag) {
        if (count1 >= 500) {
          count1 = 0;
          this.smr--;
        }
        while (true) {
          this.x = random(x - r + 1, x + r - 1);
          this.y = random(y - r + 1, y + r - 1);
          if (this.x * this.x + this.y * this.y < r * r - 2)
            break
        }
        for (let i = 0; i < krr.length; i++) {
          if (dist(krr[i].x, krr[i].y, this.x, this.y) < r + this.smr) {
            flag1 = 1
            count1++;
            break;
          }
          flag1 = 0;
        }
      }

    }
    this.ccc = createVector(random(255), random(100, 255), random(100, 255))

  }

  show() {
    stroke(0);
    noFill();
    strokeWeight(3)
    stroke(this.ccc.x, this.ccc.y, this.ccc.z);
    circle(this.x, this.y, this.smr)
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
  • Yes, please post complete code (https://stackoverflow.com/help/minimal-reproducible-example). Preferably as a runnable snippet (https://stackoverflow.com/questions/67410651/how-do-i-include-a-runnable-p5-js-sketch-in-a-stackoverflow-question). 1) it is way easier to identify issues when you can run the code because you can check the console output and use the debugger, 2) reading code that you cannot run and guessing what should happen is onerous, and 3) half the time when somebody posts only part of their code the bug is in the part they didn't post! – Paul Wheeler Nov 10 '21 at 10:03
  • Note: minimizing the amount of code is good, but not if it sacrifices reproducibility! You want to remove extra complexity if possible, why still leaving the code runnable in a way that reproduces the issue you are trying to solve. – Paul Wheeler Nov 10 '21 at 10:04
  • I have added the whole code now. Thanks for response. – Abdul Azeem Nov 10 '21 at 10:33
  • 2
    Lotsa math there and iterative logic - don't quite have time right now to work it out but I can help with some quick troubleshooting... If it's hanging, it's almost certainly in one of those loops. `while(true)` always make me nervous in javascript. Put some console.log() statements in your loops and run it with the console open, you should see where it's hanging really quick. Also adding a mechanism to opt for a default if the randoms can't generate an acceptable result within X loops might help fail gracefully. – Count Spatula Nov 10 '21 at 21:19

1 Answers1

1

Your logic for finding viable x/y values randomly in the cirgain constructor seems broken. Several of your while loops seem like they never exit.

let cir = [];
let krr = [];
let maxR;

function setup() {
  createCanvas(windowWidth, windowHeight);
  maxR = width / 4;
  if (height > width) {
    maxR = height / 4;
  }
  colorMode(HSB);
  angleMode(DEGREES);
}

function draw() {
  background(0);
  print(cir.length, krr.length);
  if (cir.length <= 100) {
    let temp = new c();
    cir.push(temp);
  } else if (krr.length < 100) {
    print(1)
    fr = cir[0]
    if (fr.r > 50) {
      let re = new cirgain(fr.x, fr.y, (fr.r) / 2)
      krr.push(re);
    }
  }
  for (let h of krr) {
    h.show();
  }

  for (let g of cir) {
    g.show();
    g.grow();

  }

}

class c {
  constructor() {
    this.tempr = 1
    if (cir.length == 0) {
      this.x = random(maxR + 1, width - maxR - 1);
      this.y = random(maxR + 1, height - maxR - 1)
      this.r = maxR;
    } else {
      let flag = 1
      let count = 0
      while (flag) {
        if (count >= 500) {
          count = 0;
          maxR--;
        }
        this.x = random(maxR / 2 + 1, width - maxR / 2 - 1);
        this.y = random(maxR / 2 + 1, height - maxR / 2 - 1);
        this.r = maxR;
        for (let i = 0; i < cir.length; i++) {
          if (dist(cir[i].x, cir[i].y, this.x, this.y) < cir[i].r / 2 + this.r / 2 + 3) {
            flag = 1
            count++;
            break;
          }
          flag = 0;
        }
      }

    }
    this.cc = createVector(random(255), random(100, 255), random(100, 255))

  }

  show() {
    stroke(0);
    noFill();
    strokeWeight(3)
    stroke(this.cc.x, this.cc.y, this.cc.z);
    circle(this.x, this.y, this.tempr)
    rectMode(CENTER);
  }
  
  grow() {
    if (this.tempr <= this.r)
      // this.tempr+=.5
      this.tempr += this.r / 100
  }
}

class cirgain {
  constructor(x, y, r) {
    this.smr = floor(r / 3);
    if (krr.length == 0) {
      let n = 0;
      while (++n < 1000) {
        this.x = random(x - r + 1, x + r - 1);
        this.y = random(y - r + 1, y + r - 1);
        if (this.x * this.x + this.y * this.y < r * r - 2) {
          break;
        }
      }
      if (n >= 1000) {
        console.warn('1. Unable to find an x/y value that satisfied the constraint');
        debugger;
      }
    } else {
      let flag1 = 1;
      let count1 = 0;
      let n = 0;
      while (flag1 && ++n < 10000) {
        if (count1 >= 500) {
          count1 = 0;
          this.smr--;
        }
        let n2 = 0;
        while (++n2 < 1000) {
          this.x = random(x - r + 1, x + r - 1);
          this.y = random(y - r + 1, y + r - 1);
          if (this.x * this.x + this.y * this.y < r * r - 2) {
            break;
          }
        }
        if (n2 >= 1000) {
          console.warn('2. Unable to find an x/y value that satisfied the constraint');
          debugger;
        }
        for (let i = 0; i < krr.length; i++) {
          if (dist(krr[i].x, krr[i].y, this.x, this.y) < r + this.smr) {
            flag1 = 1
            count1++;
            break;
          }
          flag1 = 0;
        }
      }
      
      if (n >= 10000) {
        console.warn('3. Flag never set to false');
        debugger;
      }
    }
    
    this.ccc = createVector(random(255), random(100, 255), random(100, 255))
  }

  show() {
    stroke(0);
    noFill();
    strokeWeight(3)
    stroke(this.ccc.x, this.ccc.y, this.ccc.z);
    circle(this.x, this.y, this.smr);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

Update

You seem to have an error in your logic checking if the randomly generated x/y values are acceptable:

  // Instead of this, which checks if the square of the distance from the top left (0, 0) to the randomly generated center is less than the radius squared
  if (this.x * this.x + this.y * this.y < r * r - 2) {
    break;
  }

  // You probably meant to check if the distance from the center of the circle to the randomly generated position is less than the radius:
  if (dist(x, y, this.x, this.y) < r - 2) {
    break;
  }

Additionally I cannot make heads or tails of this logic:

for (let i = 0; i < krr.length; i++) {
  if (dist(krr[i].x, krr[i].y, this.x, this.y) < r + this.smr) {
    flag1 = 1
    count1++;
    break;
  }
  flag1 = 0;
}

For each cirgain that you create you are check that for every existing cirgain the new one has a distance from the existing that is less than the containing circle's radius plus the current circle's diameter*, and if that is the case (which it almost always is!) you try to find a different random position, and only after 500 attempts you decrease the current circle's radius. I can hardly tell what your objective is, but there has to be a better way.

* You're using the default ellipse mode, which means the third argument to circle() is the diameter, which makes this code especially confusing

Paul Wheeler
  • 18,988
  • 3
  • 28
  • 41
  • Thank you so much. I wasn't considering about whole diameter and radius thing and also I was checking for wrong things. I changed some conditions and now my code runs perfectly. Should I post it here or somewhere? (Sorry, I don't quite know the stackoverflow culture). – Abdul Azeem Nov 13 '21 at 15:38
  • Thanks for accepting the answer, that is always much appreciated in the StackOverflow community. It is not necessary to post you corrected code, although you can post a separate answer to your own question if you think it might help people who have a similar question in the future. Or you can just link to it in a comment, I’m curious to see your results myself. – Paul Wheeler Nov 13 '21 at 19:05
  • [link](https://editor.p5js.org/Abdul_Azeem/sketches/Caf19qmMW) Most of the changes were in the condition checking. I was checking diameter instead of radius, also somewhere I was checking against the wrong radius as @paul-wheeler said. – Abdul Azeem Nov 13 '21 at 19:48