当我尝试在圆圈内填充圆圈时,为什么我的代码会卡住?

Why my code get stuck when I try to fill circle inside the circle?

我正在尝试简单的圆圈填充并且它有效。但是当我尝试用更多圆圈填充第一个圆圈时,它会立即挂起程序。这是我的绘图和 class 代码,它填充圆圈内的圆圈:

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)
  }
}

如果需要整个代码(包括设置和 class c(最初用圆圈填充 space)),请告诉我,我会编辑以包含它。

编辑:好的,这是完整的代码:

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>

您在 cirgain 构造函数中随机查找可行 x/y 值的逻辑似乎已损坏。您的几个 while 循环似乎永远不会退出。

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>

更新

您在检查随机生成的 x/y 值是否可接受的逻辑中似乎有错误:

  // 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;
  }

此外,我无法理解这个逻辑:

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;
}

对于您创建的每个 cirgain,您要检查每个现有的 cirgain 新的与现有的 的距离是否小于包含圆的半径 加上当前圆的 直径 *,如果是这种情况(几乎总是如此!),您尝试找到一个不同的随机位置,并且只有在尝试 500 次后您减小当前圆的半径。我几乎不知道你的 objective 是什么,但必须有更好的方法。

* 您正在使用默认的椭圆模式,这意味着 circle() 的第三个参数是 直径 ,这使得这段代码特别混乱