此代码为 grid<=11 运行,但在 grid>=12 时永远卡住。谁能解释为什么会这样?(使用 p5.js JavaScript 库)



基本上就是标题。我把每一行都读了很多遍,仍然找不到我的错误。我只是想通过调用一个递归函数来将正方形放在网格上,该函数创建对象,然后再次调用它自己。我已经检查了递归不是无限的,并且有一个简单的退出条件。请帮忙。

let grid = 11;
let sqr = [];
function setup() {
createCanvas(grid * grid, grid * grid);
noFill();
colorMode(HSB);
noLoop();
let maxs = floor(grid / 3);
let ratio = 2 * maxs * maxs;
makegrid(maxs, ratio);
}
function draw() {
background(0);
for (let sq of sqr) sq.show();
}
function makegrid(m, r) {
if (!m) return;
if (m == floor(grid / 3)) {
for (let i = 0; i < 2; i++) sqr.push(new sqrs(m, r));
m--;
makegrid(m, r);
} else {
let j = r / (m * m);
for (let k = 0; k < j; k++) sqr.push(new sqrs(m, r));
m--;
makegrid(m, r);
}
}
class sqrs {
constructor(m, r) {
let flag = true;
this.s = (m * width) / grid;
while (flag) {
flag = false;
this.x = (width / grid) * floor((grid + 1 - m) * random());
this.y = (height / grid) * floor((grid + 1 - m) * random());
if (!sqr.length) flag = false;
else {
for (let sq of sqr) {
let d = (this.x - sq.x) ** 2 + (this.y - sq.y) ** 2;
if (d < this.s ** 2 || d < sq.s ** 2) {
flag = true;
break;
}
}
}
}
}
show() {
stroke(random(340), 80, 80);
square(this.x, this.y, this.s);
}
}

正如Jay在评论中指出的,问题不是递归,而是sqrs构造函数中的while (flag)循环:

let grid = 12;
let sqr = [];
function setup() {
createCanvas(grid * grid, grid * grid);
noFill();
colorMode(HSB);
noLoop();
// maxs will be 4 if grid is 12
let maxs = floor(grid / 3);
// ratio will be 32
let ratio = 2 * maxs * maxs;
makegrid(maxs, ratio);
}
function draw() {
background(0);
for (let sq of sqr) sq.show();
}
function makegrid(m, r) {
if (m <= 0) return;
if (m == floor(grid / 3)) {
// Call 0: m == floor(grid / 3) == 4
for (let i = 0; i < 2; i++) sqr.push(new sqrs(m, r));
m--;
// Call 0: makegrid(3, 32);
makegrid(m, r);
} else {
// Call 1: j = 32 / (3 * 3) = 3.55555
// Call 2: j = 32 / (2 * 2) = 8
// Call 3: j = 32 / (1 * 1) = 32
let j = r / (m * m);
for (let k = 0; k < j; k++) sqr.push(new sqrs(m, r));
m--;
// Call 1: makegrid(2, 32)
// Call 2: makegrid(1, 32)
// Call 3: makegrid(0, 32)
makegrid(m, r);
}
}
class sqrs {
constructor(m, r) {
let flag = true;
this.s = (m * width) / grid;
// This code might end up repeating forever because every randomly generated
// position is too close to some existing square
let count = 0;
while (flag && ++count < 1000) {
flag = false;
this.x = (width / grid) * floor((grid + 1 - m) * random());
this.y = (height / grid) * floor((grid + 1 - m) * random());
if (sqr.length) {
// Check if the new square is too close to any existing squares
for (let sq of sqr) {
let d = (this.x - sq.x) ** 2 + (this.y - sq.y) ** 2;
if (d < this.s ** 2 || d < sq.s ** 2) {
flag = true;
break;
}
}
}
}
if (flag) {
this.s = 0;
print(`gave up after ${count} attempts to find a position for this square.`);
}
}
show() {
stroke(random(340), 80, 80);
square(this.x, this.y, this.s);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

while循环中的逻辑对我来说没有多大意义,所以如果你想要更多的建议,你必须描述你实际上想做什么。

最新更新