p5.js实现圆内嵌套填充圆功能时代码直接卡死是什么原因
卡死的核心原因与修复方案
问题1:未定义变量导致死循环
cirgain类的非首个子圆创建分支中,你写了while (flag),但该作用域内仅定义了flag1变量,flag属于未定义变量,判断永远为真,进入无限死循环直接卡死程序。
问题2:子圆是否在父圆内的判断逻辑错误
你用画布全局坐标this.x、this.y直接平方和计算和父圆的位置关系,正确逻辑应该是计算子圆圆心相对于父圆圆心的偏移量再判断是否在父圆内。
问题3:子圆碰撞检测逻辑错误
当前碰撞条件误用父圆半径r作为已有子圆的半径,正确的碰撞阈值应该是已有子圆半径krr[i].smr加上当前子圆半径this.smr。
修复后的完整cirgain类代码
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); // 计算相对于父圆圆心的偏移 let dx = this.x - x; let dy = this.y - y; if (dx * dx + dy * dy < (r - this.smr/2) * (r - this.smr/2) - 2) { break; } } } else { let flag1 = 1; let count1 = 0; // 把未定义的flag改为flag1 while (flag1) { if (count1 >= 500) { count1 = 0; this.smr--; // 半径小于1直接退出,避免死循环 if (this.smr < 1) break; } // 先生成在父圆范围内的坐标 while (true) { this.x = random(x - r + 1, x + r - 1); this.y = random(y - r + 1, y + r - 1); let dx = this.x - x; let dy = this.y - y; if (dx * dx + dy * dy < (r - this.smr/2) * (r - this.smr/2) - 2) { break; } } // 碰撞检测,判断和已有子圆是否重叠 flag1 = 0; for (let i = 0; i < krr.length; i++) { // 正确的碰撞阈值:两个子圆的半径之和 if (dist(krr[i].x, krr[i].y, this.x, this.y) < krr[i].smr + this.smr + 2) { flag1 = 1; count1++; break; } } } } 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); } }
额外优化点
- 新增了子圆半径小于1时的退出逻辑,避免空间不足时永远循环
- 子圆范围判断扣除了自身半径,避免子圆边缘超出父圆范围
- 碰撞检测增加了2像素的间隙,避免子圆紧贴
内容的提问来源于stack exchange,提问作者Abdul Azeem
相关产品推荐
相关产品推荐

