fogón

← Fiestas y NavidadObjeto 3Dfogon/pinata

Piñata

de fogonCC06239 bloques
PiñataArrastrá para girarlo
// «Piñata» · gpt-6-sol (medium)
// A colorful star-shaped Mexican piñata hanging from a rope on a wooden post: a round center body with seven cones sticking out, covered in fringed paper stripes of pink, yellow, turquoise and orange, with long colorful tassels hanging from the tips of the cones.

// Wooden stand and crossbar
box(2, 21, 0, 13, 31, 2, "#8b5430");
box(3, 22, 2, 12, 30, 3, "#ad7240");
box(5, 24, 3, 9, 28, 45, "#a96535");
box(5, 24, 4, 6, 24, 44, "#c98a4e");
box(8, 27, 4, 9, 28, 43, "#784522");
box(6, 23, 44, 28, 27, 46, "#a96535");
box(7, 23, 46, 27, 24, 46, "#d49a5c");
box(7, 27, 44, 27, 27, 45, "#784522");

for (let z = 6; z < 43; z += 7) {
  line(5, 23, z, 5, 23, z + 3, 0, "#dc9c60");
  line(8, 24, z + 2, 8, 24, z + 4, 0, "#85502d");
}
box(25, 22, 44, 29, 28, 45, "#e7b84f");
box(26, 22, 45, 28, 23, 45, "#ffe28a");

// The rope and entire piñata swing together from the crossbar.
part("pinata", [27, 23, 44]);

line(27, 23, 44, 27, 23, 40, 1, "#eac66f");
line(26, 22, 43, 26, 22, 41, 0, "#fff0a6");
sphere(27, 23, 40, 1.5, "#f4cc63");

const cx = 27, cy = 23, cz = 21;
const bands = [
  ["#e9448f", "#ff83bb", "#bc2a69"], // pink
  ["#ffd74e", "#fff187", "#d4a835"], // lemon
  ["#25c9c5", "#78eee1", "#159795"], // turquoise
  ["#ff923e", "#ffc06b", "#d5682d"]  // orange
];

// Solid, rounded center with broad bands of fringed tissue paper.
for (let x = cx - 8; x <= cx + 8; x++)
for (let y = cy - 8; y <= cy + 8; y++)
for (let z = cz - 8; z <= cz + 8; z++) {
  const d = ((x-cx)/8)**2 + ((y-cy)/8)**2 + ((z-cz)/8)**2;
  if (d > 1) continue;
  const band = bands[((Math.floor((z - 13) / 3) % 4) + 4) % 4];
  const shade = y < cy - 3 || z > cz + 5 ? 1 : y > cy + 3 ? 2 : 0;
  set(x, y, z, band[rand() < 0.08 ? (shade + 1) % 3 : shade]);
}

// Little loose paper edges on the viewer-facing side of the round body.
for (let z = 15; z <= 27; z += 3)
for (let x = cx - 7; x <= cx + 7; x++) {
  const q = 64 - (x-cx)**2 - (z-cz)**2;
  if (q < 5 || rand() < 0.23) continue;
  const y = Math.round(cy - Math.sqrt(q));
  const color = bands[Math.floor((z - 13) / 3) % 4][1];
  set(x, y - 1, z, color);
  if (rand() < 0.65) set(x, y - 1, z - 1, color);
}

// Seven striped, tapered points radiating around the center.
for (let i = 0; i < 7; i++) {
  const a = Math.PI / 2 + i * 2 * Math.PI / 7;
  const ux = Math.cos(a), uz = Math.sin(a);

  for (let x = 8; x <= 46; x++)
  for (let z = 2; z <= 42; z++) {
    const dx = x - cx, dz = z - cz;
    const s = dx * ux + dz * uz;
    if (s < 6 || s > 19) continue;
    const t = -dx * uz + dz * ux;
    const r = Math.max(0.6, 5.25 * (19 - s) / 13);
    if (Math.abs(t) > r) continue;

    for (let y = 17; y <= 29; y++) {
      if (t*t + ((y-cy)*1.05)**2 > r*r) continue;
      const stripe = Math.floor((s - 6) / 2.15) % 4;
      const band = bands[(stripe + i) % 4];
      const shade = y < cy - 1 || z > cz + 3 ? 1 : y > cy + 2 ? 2 : 0;
      set(x, y, z, band[rand() < 0.045 ? (shade + 1) % 3 : shade]);
    }
  }

  // Short, individually cut fringe along the front of each cone.
  for (let s = 8; s <= 17; s += 3)
  for (let t = -4; t <= 4; t++) {
    const r = Math.max(0.6, 5.25 * (19 - s) / 13);
    if (Math.abs(t) >= r - 0.3 || rand() < 0.22) continue;
    const x = Math.round(cx + ux*s - uz*t);
    const z = Math.round(cz + uz*s + ux*t);
    const y = Math.round(cy - Math.sqrt(Math.max(0, r*r - t*t)) / 1.05) - 1;
    const color = bands[(Math.floor((s-6)/2.15) + i) % 4][1];
    set(x, y, z, color);
    if (rand() < 0.7) set(x, y, z - 1, color);
  }

  const tx = Math.round(cx + 19*ux);
  const tz = Math.round(cz + 19*uz);
  sphere(tx, cy, tz, 1.35, bands[(i + 2) % 4][1]);

  // Long, loose tassel ribbons hang vertically from every point.
  const ribbons = ["#ff63aa", "#ffe35e", "#37dfd5", "#ffa24e", "#c995ef"];
  for (let k = 0; k < 6; k++) {
    const spread = k - 2.5;
    const y = cy + Math.round(spread * 0.7);
    const x = tx + Math.round(spread * 0.55);
    const length = 4 + (k % 3) + (tz < 12 ? 1 : 0);
    for (let n = 1; n <= length && tz - n >= 0; n++) {
      const flutter = n > 3 ? Math.round(Math.sin(n * 1.4 + k) * 0.8) : 0;
      set(x + flutter, y, tz - n, ribbons[(k + i) % ribbons.length]);
      if (n < 3) set(x + flutter, y + 1, tz - n, ribbons[(k + i) % ribbons.length]);
    }
  }
}

animate("pinata", { type: "swing", axis: "x", speed: 2, amplitude: 0.35 });