实现含单个大尺寸Tile的网格:解决drawSubdividedCircle重叠问题
几何网格图形程序问题修复
需求与问题
- 需求:让
drawSubdividedCircle函数仅在网格的随机位置出现一次,且占据两行两列的宽高 - 当前问题:运行时图形重叠,核心原因是原代码绘制逻辑混乱,既没有限制细分圆的出现次数,也未处理其占用的网格区域
- 目标效果:

当前代码
let colors = [ "#F7F7F7", "#141414", "#f07f45", "#bcaad6", "#60388e", "#00afc6", "#aae3ea" ]; let tilesX = 5; let tilesY = 5; let tileW; let tileH; let tileSize; function drawSubdividedCircle (x, y, size, segments, layers) { segments = random (1,13); layers = random (1,13); const r = 360 / segments; for (let i = 0; i < segments; i++) { for (let j = 0; j < layers; j++) { fill(random(colors)); const s = map(j, 0, layers, size, 0); arc( x + size / 2, y + size / 2, s, s, radians(r * i), radians(r * (i + 1))); } } } function setup() { createCanvas(500, 500, SVG); tileW = width / tilesX; tileH = height / tilesY; tileSize = (tileW, tileH); // 语法错误:无效赋值逻辑 } function draw() { noStroke(); frameRate(2); for (let x = 0; x < tilesX; x++) { for (let y = 0; y < tilesY; y++) { let r = random(1); if (r < 0.5) { ellipse((x - 0.5) * tileSize, (y - 0.5) * tileSize, tileSize, tileSize); fill(random(colors)); } else { rect(x * tileSize, y * tileSize, tileSize, tileSize); fill(random(colors)); }{ drawSubdividedCircle(x * tileSize, y * tileSize, tileSize*2); fill(random(colors)); } } } //save("sketch1.6.5.svg"); //print("saved svg"); //noLoop(); }
修复方案
关键修改点
- 修正语法错误:删除
else块后非法的}{;将tileSize = (tileW, tileH)改为tileSize = min(tileW, tileH),保证格子为正方形。 - 控制细分圆单一出现:提前生成合法随机起始坐标,确保2x2区域不超出网格范围。
- 跳过占用区域绘制:循环绘制普通图形时,跳过被细分圆占用的4个格子,避免重叠。
- 调整绘制顺序:先完成所有普通图形绘制,最后绘制细分圆,保证视觉层级正确。
修改后的完整代码
let colors = [ "#F7F7F7", "#141414", "#f07f45", "#bcaad6", "#60388e", "#00afc6", "#aae3ea" ]; let tilesX = 5; let tilesY = 5; let tileW; let tileH; let tileSize; function drawSubdividedCircle(x, y, size, segments, layers) { segments = random(1, 13); layers = random(1, 13); const r = 360 / segments; for (let i = 0; i < segments; i++) { for (let j = 0; j < layers; j++) { fill(random(colors)); const s = map(j, 0, layers, size, 0); arc( x + size / 2, y + size / 2, s, s, radians(r * i), radians(r * (i + 1)) ); } } } function setup() { createCanvas(500, 500, SVG); tileW = width / tilesX; tileH = height / tilesY; tileSize = min(tileW, tileH); // 修正赋值逻辑,取宽高中较小值保证正方形格子 } function draw() { noStroke(); frameRate(2); background(255); // 添加背景避免帧叠加 // 生成细分圆的随机起始位置(确保2x2区域不超出网格) const circleStartX = floor(random(tilesX - 1)); const circleStartY = floor(random(tilesY - 1)); // 先绘制所有普通椭圆/矩形,跳过被细分圆占用的格子 for (let x = 0; x < tilesX; x++) { for (let y = 0; y < tilesY; y++) { // 判断当前格子是否在2x2的细分圆区域内,是则跳过 if (x >= circleStartX && x <= circleStartX + 1 && y >= circleStartY && y <= circleStartY + 1) { continue; } let r = random(1); fill(random(colors)); if (r < 0.5) { ellipse(x * tileSize + tileSize / 2, y * tileSize + tileSize / 2, tileSize, tileSize); } else { rect(x * tileSize, y * tileSize, tileSize, tileSize); } } } // 最后绘制唯一的2x2细分圆 drawSubdividedCircle(circleStartX * tileSize, circleStartY * tileSize, tileSize * 2); //save("sketch1.6.5.svg"); //print("saved svg"); //noLoop(); }
代码说明
circleStartX/circleStartY:通过floor(random(tilesX - 1))生成合法起始坐标,确保细分圆不会超出5x5网格边界。- 占用区域判断:跳过被细分圆覆盖的4个格子,彻底解决重叠问题。
- 椭圆坐标修正:将原错误的
(x - 0.5) * tileSize改为x * tileSize + tileSize / 2,使椭圆居中显示在格子内。
内容的提问来源于stack exchange,提问作者Johanna
相关产品推荐
相关产品推荐

