fogón

← Basics3D assetfogon/banqueta-de-tres-patas

Banqueta de tres patas

by fogonCC08804 blocks
Banqueta de tres patasDrag to turn it
// «Banqueta de tres patas» · gpt-6-sol (medium)
// Three legged stool («Banqueta de tres patas»).

// Three-legged wooden stool
const woodDark = "#805027";
const woodShadow = "#94602d";
const woodMid = "#ae7337";
const woodLight = "#c58b45";
const woodHighlight = "#d89e53";

const legs = [
  { top: [19, 16], foot: [18, 10] }, // front
  { top: [13, 29], foot: [10, 33] }, // rear left
  { top: [34, 29], foot: [37, 33] }  // rear right
];

function legCenter(leg, z) {
  const t = Math.min(1, z / 34);
  return [
    Math.round(leg.foot[0] * (1 - t) + leg.top[0] * t),
    Math.round(leg.foot[1] * (1 - t) + leg.top[1] * t)
  ];
}

// Low, chunky triangular footrest and its darker lower edges.
function beam(a, b, z) {
  line(a[0], a[1], z, b[0], b[1], z, 1.25, woodShadow);
  line(a[0], a[1] - 1, z + 1, b[0], b[1] - 1, z + 1, 0, woodLight);
  line(a[0], a[1], z - 1, b[0], b[1], z - 1, 0, woodDark);
}
beam(legCenter(legs[0], 15), legCenter(legs[1], 15), 15);
beam(legCenter(legs[0], 15), legCenter(legs[2], 15), 15);
beam(legCenter(legs[1], 17), legCenter(legs[2], 17), 17);

// Short structural rails immediately beneath the seat.
beam(legCenter(legs[0], 31), legCenter(legs[1], 31), 31);
beam(legCenter(legs[0], 31), legCenter(legs[2], 31), 31);
beam(legCenter(legs[1], 31), legCenter(legs[2], 31), 31);

// Four-sided legs, subtly splayed outward at their feet.
for (let i = 0; i < legs.length; i++) {
  for (let z = 0; z <= 35; z++) {
    const [cx, cy] = legCenter(legs[i], z);
    const width = z < 5 ? 4 : (z > 27 ? 5 : 4);
    const lo = -Math.floor(width / 2);
    const hi = lo + width - 1;
    for (let dx = lo; dx <= hi; dx++) {
      for (let dy = lo; dy <= hi; dy++) {
        let color = woodMid;
        if (dy === lo) color = woodLight;
        if (dx === hi) color = woodShadow;
        if (dy === hi) color = woodDark;
        if (dx === lo && dy === lo) color = woodHighlight;
        if (z % 8 === 2 && dx === lo && dy === lo) color = woodMid;
        if (rand() < 0.045) color = dy === lo ? woodHighlight : woodShadow;
        set(cx + dx, cy + dy, z, color);
      }
    }
  }

  // Squared-off joinery collars at the footrest and seat.
  for (const z of [14, 15, 29, 30]) {
    const [cx, cy] = legCenter(legs[i], z);
    box(cx - 2, cy - 2, z, cx + 2, cy + 2, z, z === 14 || z === 29 ? woodDark : woodLight);
    box(cx - 2, cy - 2, z, cx + 1, cy - 2, z, woodHighlight);
  }
}

// Thick round seat: dark underside, warm carved rim, pale planked top.
const sx = 24, sy = 24;
const layers = [
  { z: 33, r: 17.2, base: "#865326" },
  { z: 34, r: 18.2, base: "#a66a31" },
  { z: 35, r: 19.0, base: "#9d642e" },
  { z: 36, r: 19.3, base: "#bb7b37" },
  { z: 37, r: 19.0, base: "#d99648" },
  { z: 38, r: 18.3, base: "#f5b761" }
];

for (const layer of layers) {
  for (let x = 4; x <= 44; x++) {
    for (let y = 4; y <= 44; y++) {
      const d = Math.hypot(x - sx, y - sy);
      if (d > layer.r) continue;

      let color = layer.base;
      if (layer.z === 38) {
        // Long, slightly diagonal boards, with narrow seams and fine grain.
        const plank = x + 0.32 * (y - sy);
        const band = Math.floor(plank / 5);
        const shades = ["#f9be6b", "#efab56", "#f6b965", "#f2b15b", "#ffca76"];
        color = shades[((band % shades.length) + shades.length) % shades.length];
        const seam = ((plank % 5) + 5) % 5;
        if (seam < 0.48) color = "#d79548";
        else if (seam < 1.05) color = "#ffca78";
        if (rand() < 0.11) color = rand() < 0.58 ? "#ffd082" : "#e9a454";
        if (d > 17.1) color = y < 24 ? "#d89445" : "#e4a451";
      } else if (d > layer.r - 1.5) {
        color = y < 23 ? "#98602d" : "#b67636";
        if (layer.z >= 36) color = y < 23 ? "#bb7c39" : "#ce8a43";
        if (rand() < 0.22) color = "#db9850";
      } else if (rand() < 0.075) {
        color = layer.z < 36 ? "#b77b39" : "#e7a650";
      }
      set(x, y, layer.z, color);
    }
  }
}

// Individually visible, blocky end-grain marks around the seat's front lip.
for (let a = 0; a < Math.PI * 2; a += 0.115) {
  const x = Math.round(sx + 18.7 * Math.cos(a));
  const y = Math.round(sy + 18.7 * Math.sin(a));
  set(x, y, 36, rand() < 0.35 ? "#a56830" : "#bb7938");
  if (rand() < 0.72) set(x, y, 37, "#d39247");
}