fogón

← Whole house3D assetfogon/puff

Puff

by fogonCC018573 blocks
PuffDrag to turn it
// «Puff» · gpt-6-sol (medium)
// A round soft pouf (ottoman): a fat cylinder of knitted fabric in coral pink with a chunky braided texture made of alternating shades, a slightly domed top with a button in the center.

const cx = 24, cy = 24;
const radii = [
  14.8, 15.9, 16.5, 17.0, 17.1, 17.1, 17.1, 17.1,
  17.1, 17.1, 17.1, 17.1, 17.05, 16.95, 16.8, 16.55,
  16.2, 15.6, 14.9, 13.9, 12.4, 10.5, 7.7, 3.9
];

const coral = ["#d87875", "#e38a83", "#ec9990", "#f4aaa0"];
const yarnLight = ["#f6aaa0", "#ffc0af"];
const tau = Math.PI * 2;

for (let z = 0; z < radii.length; z++) {
  for (let y = 5; y <= 43; y++) {
    for (let x = 5; x <= 43; x++) {
      const dx = x - cx, dy = y - cy;
      const d = Math.hypot(dx, dy);
      const a = Math.atan2(dy, dx);
      const around = (a + Math.PI) * 25 / tau;

      // Paired, slanting loops make a chunky knitted V on the barrel.
      const row = Math.floor((z - 2) / 4);
      const rise = ((z - 2) % 4 + 4) % 4 / 4;
      const stitch = around + (row & 1) * 0.5;
      const across = ((stitch % 1) + 1) % 1;
      const v = Math.abs(across - 0.5);
      const raised = z >= 2 && z <= 16 &&
        Math.abs(v - (0.08 + 0.32 * rise)) < 0.13;

      const outer = radii[z] + (raised ? 0.42 : 0);
      if (d > outer) continue;

      const side = d > radii[z] - 2.3;
      const top = z >= 17 && d > (radii[z + 1] ?? -1);
      let color = coral[1];

      if (z <= 2) {
        color = z === 0 ? "#bd6869" : "#d17b76";
      } else if (side && z <= 16) {
        const alternate = (Math.floor(stitch) + row) & 1;
        color = alternate ? coral[1] : coral[2];
        if (raised) color = yarnLight[alternate];
        else if (Math.abs(v - (0.08 + 0.32 * rise)) < 0.22)
          color = "#cb706e";
      } else if (top) {
        color = "#efa097";
        // Soft concentric rows of little knitted loops on the domed seat.
        const ring = Math.floor(d / 2.5);
        const loop = (a + Math.PI) * (12 + ring * 3) / tau + (ring & 1) * 0.5;
        const phase = ((loop % 1) + 1) % 1;
        if (Math.abs(phase - 0.5) < 0.22)
          color = ring & 1 ? "#f8b0a4" : "#f5a79e";
        if (d > 12.5) color = "#e68d86";
      } else if (z > 14) {
        color = "#e9948b";
      }

      if (side && !raised && rand() < 0.055)
        color = z < 12 ? "#da807b" : "#e99991";

      set(x, y, z, color);
    }
  }
}

// A thick, tidy piping seam where the rounded top meets the sides.
for (let i = 0; i < 360; i++) {
  const a = i * tau / 360;
  set(cx + Math.cos(a) * 16.0, cy + Math.sin(a) * 16.0, 16, "#f6aaa0");
  if (i % 9 < 5)
    set(cx + Math.cos(a) * 15.5, cy + Math.sin(a) * 15.5, 17, "#e2837d");
}

// Small recessed tuft and a plump fabric-covered button.
ellipsoid(cx, cy, 23, 3.5, 3.5, 0.8, "#d47776");
ellipsoid(cx, cy, 24, 2.6, 2.6, 1.3, "#ffc3af");
ellipsoid(cx, cy, 25, 1.8, 1.8, 0.6, "#ffd1ba");
set(23, 24, 25, "#be7773");
set(25, 24, 25, "#be7773");