fogón

← Asian3D assetfogon/faroles-rojos

Faroles rojos

by fogonCC05506 blocks
Faroles rojosDrag to turn it
// «Faroles rojos» · gpt-6-sol (medium)
// Two wooden posts with a beam between them, hanging three round red paper lanterns with gold caps and tassels. The lanterns are the moving part: they sway gently.

// Stone feet and red-lacquered posts.
for (const x of [6, 41]) {
  box(x - 3, 20, 0, x + 3, 28, 1, "#aaa9a0");
  box(x - 2, 21, 2, x + 2, 27, 3, "#e3ded0");
  box(x - 2, 22, 4, x + 2, 26, 33, "#8e211c");
  box(x - 2, 22, 4, x + 2, 22, 33, "#bf3829");
  box(x - 2, 22, 4, x - 2, 26, 33, "#a72c22");
  for (const z of [5, 9, 29, 32]) {
    box(x - 2, 21, z, x + 2, 27, z, "#d5a34c");
    box(x - 1, 21, z, x + 1, 21, z, "#f4cb70");
  }
  box(x - 3, 21, 31, x + 3, 27, 33, "#71201c");
}

// Crossbeam, with a bright front edge.
box(5, 22, 33, 43, 26, 36, "#85231d");
box(5, 22, 34, 43, 22, 36, "#b93226");
box(5, 21, 33, 43, 21, 33, "#e0aa50");
box(5, 21, 36, 43, 21, 36, "#efc36a");
box(9, 21, 30, 11, 25, 32, "#a82c23");
box(37, 21, 30, 39, 25, 32, "#a82c23");

// A shallow glazed-tile canopy with upturned ends.
for (let x = 3; x <= 45; x++) {
  for (let y = 18; y <= 30; y++) {
    const rise = Math.floor((6 - Math.abs(y - 24)) / 3);
    const tip = (x <= 5 || x >= 43) ? 1 : 0;
    const z = 38 + rise + tip;
    set(x, y, z - 1, "#263f38");
    set(x, y, z, (x + y) % 4 === 0 ? "#598478" : "#39665c");
    if (x % 4 === 0 && y > 18 && y < 30) set(x, y, z, "#729789");
  }
}
for (const y of [18, 30]) {
  for (let x = 3; x <= 45; x++) {
    set(x, y, (x <= 5 || x >= 43) ? 40 : 38, "#244c49");
  }
}
box(5, 23, 41, 43, 25, 41, "#638c7c");

// Each lantern, including its cord, has its own hanging pivot.
const lanterns = [
  { x: 14, speed: 1.05, amplitude: 0.22 },
  { x: 24, speed: 0.88, amplitude: 0.26 },
  { x: 34, speed: 1.16, amplitude: 0.20 }
];

for (let i = 0; i < lanterns.length; i++) {
  const { x, speed, amplitude } = lanterns[i];
  const name = `lantern${i + 1}`;
  part(name, [x, 20, 33]);

  box(x, 20, 30, x, 20, 32, "#e7b85e");
  box(x - 1, 19, 29, x + 1, 21, 29, "#efcb78");

  // Solid, rounded paper body, shaded toward its front and underside.
  for (let dx = -4; dx <= 4; dx++) {
    for (let dy = -4; dy <= 4; dy++) {
      for (let dz = -5; dz <= 5; dz++) {
        if ((dx * dx + dy * dy) / 16 + dz * dz / 25 > 1) continue;
        let color = dy <= -2 ? "#ed5140" : "#c52c2b";
        if (dz < -2) color = dy <= -2 ? "#d93a32" : "#a82427";
        if (dy >= 2) color = "#a82327";
        if (rand() < 0.08) color = dy < 0 ? "#f1644c" : "#b42a29";
        set(x + dx, 20 + dy, 22 + dz, color);
      }
    }
  }

  // Fine gold ribs following the curved front of the paper.
  for (const dx of [-2, 2]) {
    for (let z = 19; z <= 25; z++) {
      const q = 1 - dx * dx / 16 - (z - 22) ** 2 / 25;
      if (q > 0) {
        const frontY = 20 - Math.floor(4 * Math.sqrt(q));
        set(x + dx, frontY - 1, z, "#d8994a");
      }
    }
  }

  cylinder(x, 20, 27, 2, 2, "#d8a547");
  box(x - 1, 19, 28, x + 1, 21, 28, "#f5d079");
  cylinder(x, 20, 16, 2, 2, "#d4a04b");
  box(x - 1, 18, 18, x + 1, 18, 18, "#f4cf76");

  // A small, legible gold emblem on the front.
  set(x, 15, 22, "#f7d27c");
  set(x, 16, 23, "#f7d27c");
  set(x - 1, 16, 21, "#e9b75d");
  set(x + 1, 16, 21, "#e9b75d");

  box(x, 20, 13, x, 20, 15, "#e8b95d");
  for (let t = -1; t <= 1; t++) {
    box(x + t, 20, 10 + Math.abs(t), x + t, 20, 13, t === 0 ? "#efbd55" : "#a92a29");
  }

  animate(name, { type: "swing", axis: "x", speed, amplitude });
}
part("body");