You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现含单个大尺寸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();
}

修复方案

关键修改点

  1. 修正语法错误:删除else块后非法的}{;将tileSize = (tileW, tileH)改为tileSize = min(tileW, tileH),保证格子为正方形。
  2. 控制细分圆单一出现:提前生成合法随机起始坐标,确保2x2区域不超出网格范围。
  3. 跳过占用区域绘制:循环绘制普通图形时,跳过被细分圆占用的4个格子,避免重叠。
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:25:20