fogón

← BásicoObjeto 3Dfogon/colador

Colador

de fogonCC03712 bloques
ColadorArrastrá para girarlo
// «Colador» · gpt-6-sol (medium)
// Colander («Colador»).

// Brushed-metal colander with a perforated, rounded bowl.
const metal = ["#647780", "#788b93", "#91a2a8", "#aebbbd", "#c7d0cf"];

function steel(x, y, z, bright = 0) {
  let shade = 2 + bright + (z > 23 ? 0.4 : 0) + (y < 24 ? -0.35 : 0);
  shade += (rand() - 0.5) * 1.5;
  return metal[Math.max(0, Math.min(4, Math.round(shade)))];
}

function radius(z) {
  const stops = [
    [5, 6], [8, 9], [12, 12], [16, 14.5],
    [20, 16.5], [25, 18], [29, 18.8], [31, 19]
  ];
  for (let i = 1; i < stops.length; i++) {
    if (z <= stops[i][0]) {
      const [za, ra] = stops[i - 1];
      const [zb, rb] = stops[i];
      return ra + (rb - ra) * (z - za) / (zb - za);
    }
  }
  return 19;
}

// A shallow square pedestal beneath the bowl.
box(19, 19, 2, 29, 29, 3, "#778a91");
box(20, 20, 3, 28, 28, 4, "#91a2a7");
for (const x of [19, 27]) {
  for (const y of [19, 27]) {
    box(x, y, 0, x + 2, y + 2, 2, "#6b7e86");
    box(x, y, 2, x + 2, y, 2, "#a9b6b8");
  }
}

// Pierced bottom, with a stronger circular edge.
for (let x = 17; x <= 31; x++) {
  for (let y = 17; y <= 31; y++) {
    const d = Math.hypot(x - 24, y - 24);
    if (d <= 7.3 && (d > 5.5 || x % 3 === 0 || y % 3 === 0)) {
      set(x, y, 5, steel(x, y, 5));
    }
  }
}

// Horizontal hoops and closely spaced vertical ribs leave square openings.
for (let z = 6; z <= 29; z++) {
  const r = radius(z);
  for (let x = 4; x <= 44; x++) {
    for (let y = 4; y <= 44; y++) {
      const dx = x - 24, dy = y - 24;
      const d = Math.hypot(dx, dy);
      if (Math.abs(d - r) > 0.85) continue;

      let angle = Math.atan2(dy, dx);
      if (angle < 0) angle += Math.PI * 2;
      const rib = (angle * 48 / (Math.PI * 2) + 0.17) % 1;
      const hoop = z % 4 === 0 || z <= 7 || z >= 28;
      if (hoop || rib < 0.42) {
        set(x, y, z, steel(x, y, z, hoop ? 0.15 : -0.15));
      }
    }
  }
}

// Thick, continuous rolled lip around the open mouth.
for (let z = 29; z <= 32; z++) {
  for (let x = 4; x <= 44; x++) {
    for (let y = 4; y <= 44; y++) {
      const d = Math.hypot(x - 24, y - 24);
      const inner = z === 32 ? 17.35 : 17.8;
      const outer = z === 30 ? 19.3 : 19.7;
      if (d >= inner && d <= outer) {
        set(x, y, z, steel(x, y, z, z === 32 ? 1.25 : 0.45));
      }
    }
  }
}

// Two flat, open-loop lifting handles, joined to opposite sides of the rim.
for (const [x0, x1] of [[2, 9], [39, 46]]) {
  for (let x = x0; x <= x1; x++) {
    for (let y = 20; y <= 28; y++) {
      const border = x <= x0 + 1 || x >= x1 - 1 ||
                     y <= 21 || y >= 27;
      if (!border) continue;
      set(x, y, 30, steel(x, y, 30, 0.5));
      set(x, y, 31, steel(x, y, 31, 1));
    }
  }
  // Solid neck at the attachment point.
  const a = x0 < 24 ? 8 : 39;
  box(a, 22, 29, a + 1, 26, 31, "#aebbbd");
}

// Sparse bright glints emphasize the woven metal without obscuring the holes.
forEach((x, y, z, color) => {
  if (z >= 8 && z <= 28 && rand() < 0.035) {
    set(x, y, z, "#c1cbcb");
  }
});