fogón

← Piratas y marObjeto 3Dfogon/jaula-de-prisionero

Jaula de prisionero

de fogonCC03047 bloques
Jaula de prisioneroArrastrá para girarlo
// «Jaula de prisionero» · gpt-6-sol (medium)
// A hanging cage: a tall wooden post with an arm from which hangs a round black iron bird-style cage big enough for a person, with a small skeleton hand peeking through the bars.

const wood = "#87502d", woodLight = "#ad7040", woodDark = "#60391f";
const iron = "#202830", ironLight = "#46515a", ironDark = "#11191f";
const gold = "#efbd49", bone = "#f3e4bb";
const cx = 31, cy = 24;

// A little sandy ground around the foot of the gallows.
ellipsoid(12, 24, 0, 8, 7, 1, "#eacb86");
for (let i = 0; i < 85; i++) {
  const x = 5 + Math.floor(rand() * 15);
  const y = 17 + Math.floor(rand() * 15);
  if (get(x, y, 0) === "#eacb86")
    set(x, y, 0, rand() < 0.5 ? "#f5da98" : "#dcb976");
}

// Solid, weathered wooden post.
box(10, 21, 0, 16, 27, 2, woodDark);
box(11, 22, 2, 15, 26, 41, wood);
box(11, 22, 3, 11, 26, 40, woodLight);
box(12, 22, 3, 12, 22, 40, "#bd8050");
box(15, 22, 3, 15, 26, 40, woodDark);
box(10, 21, 2, 16, 27, 3, woodLight);
box(10, 21, 37, 17, 27, 39, woodDark);

// Long projecting beam, with a chunky diagonal brace.
box(11, 22, 38, 34, 26, 41, wood);
box(12, 22, 41, 33, 22, 41, "#c18a53");
box(12, 26, 38, 33, 26, 38, woodDark);
line(15, 24, 26, 25, 24, 38, 1.5, woodDark);
line(16, 23, 27, 25, 23, 38, 0.7, woodLight);
box(32, 21, 37, 35, 27, 41, woodDark);
box(33, 22, 40, 35, 26, 41, woodLight);

// Grain and plank seams on visible faces.
for (let z = 5; z < 37; z += 5) {
  line(12, 21, z, 12, 21, z + 2, 0, woodLight);
  line(14, 21, z + 2, 14, 21, z + 3, 0, woodDark);
}
for (let x = 17; x < 32; x += 5) {
  line(x, 21, 39, x + 2, 21, 39, 0, woodLight);
  set(x + 1, 21, 38, woodDark);
}
for (const z of [5, 35]) {
  box(10, 21, z, 16, 27, z, ironDark);
  box(11, 21, z, 13, 21, z, ironLight);
  set(12, 20, z, gold);
  set(15, 20, z, gold);
}
for (const x of [15, 25, 32]) {
  set(x, 21, 39, ironDark);
  set(x, 21, 40, ironLight);
}

// All of the suspended ironwork swings together from this pin.
part("cage", [cx, cy, 36]);
animate("cage", { type: "swing", axis: "x", speed: 1.5, amplitude: 0.15 });

box(cx - 1, cy - 1, 35, cx + 1, cy + 1, 36, ironLight);
set(cx, cy - 2, 36, gold);
for (const z of [32, 34]) {
  box(cx, cy - 1, z, cx, cy + 1, z + 1, iron);
  set(cx, cy - 2, z, ironLight);
}
box(cx - 1, cy - 1, 30, cx + 1, cy + 1, 32, iron);
set(cx, cy - 2, 31, gold);

// Rounded cage profile. The hoops and vertical ribs remain open between bars.
function radius(z) {
  const profile = [
    [8, 8], [10, 9], [12, 9.8], [16, 10],
    [20, 9.4], [23, 8.2], [26, 6.2],
    [28, 4.2], [30, 1.8]
  ];
  for (let i = 1; i < profile.length; i++) {
    if (z <= profile[i][0]) {
      const a = profile[i - 1], b = profile[i];
      return a[1] + (b[1] - a[1]) * (z - a[0]) / (b[0] - a[0]);
    }
  }
  return 1.8;
}
function hoop(z, r, color, thickness) {
  const n = 84;
  for (let i = 0; i < n; i++) {
    const a = i * 2 * Math.PI / n;
    const b = (i + 1) * 2 * Math.PI / n;
    line(cx + r * Math.cos(a), cy + r * Math.sin(a), z,
         cx + r * Math.cos(b), cy + r * Math.sin(b), z,
         thickness, color);
  }
}

// Heavy round base with a visible wooden floor inside.
ellipsoid(cx, cy, 8, 8.5, 8.5, 1, ironDark);
ellipsoid(cx, cy, 9, 7.2, 7.2, 0.5, woodDark);
for (let x = 25; x <= 37; x += 3) {
  for (let y = 19; y <= 29; y++)
    if (get(x, y, 9) === woodDark) set(x, y, 9, woodLight);
}
hoop(8, 8.3, iron, 0.9);
hoop(10, radius(10), ironLight, 0.65);
hoop(20, radius(20), iron, 0.65);
hoop(26, radius(26), ironLight, 0.7);
hoop(29, radius(29), iron, 0.8);

// Fourteen stout, bowed iron bars, with lighter front-facing edges.
for (let i = 0; i < 14; i++) {
  const a = i * Math.PI * 2 / 14;
  for (let z = 8; z < 30; z++) {
    const r0 = radius(z), r1 = radius(z + 1);
    line(cx + r0 * Math.cos(a), cy + r0 * Math.sin(a), z,
         cx + r1 * Math.cos(a), cy + r1 * Math.sin(a), z + 1,
         0.55, iron);
  }
  if (Math.sin(a) < -0.35) {
    for (let z = 12; z < 25; z += 3) {
      const r = radius(z);
      set(cx + r * Math.cos(a), cy + r * Math.sin(a) - 0.5,
          z, ironLight);
    }
  }
}
hoop(8, 8.3, ironLight, 0.65);
hoop(20, radius(20), ironLight, 0.45);
hoop(29, radius(29), ironLight, 0.55);
sphere(cx, cy, 30, 2, iron);
set(cx, cy - 2, 30, gold);

// Rivets and a conspicuous little gold door latch on the front.
for (const x of [25, 31, 37]) {
  set(x, 15, 10, gold);
  set(x, 15, 20, gold);
}
box(36, 14, 15, 37, 14, 17, gold);
set(37, 13, 16, "#fff0a3");

// A skeletal arm reaches out between the bars toward the viewer.
line(34, 19, 15, 34, 13, 16, 0.75, "#d4c69e");
sphere(34, 12, 16, 1.3, bone);
line(33, 11, 16, 32, 10, 18, 0.5, bone);
line(34, 11, 17, 34, 9, 20, 0.5, bone);
line(35, 11, 17, 36, 9, 19, 0.5, bone);
line(35, 11, 16, 37, 10, 17, 0.5, bone);
line(33, 12, 15, 31, 11, 14, 0.5, bone);
for (const [x, y, z] of [
  [32, 10, 18], [34, 9, 20], [36, 9, 19],
  [37, 10, 17], [31, 11, 14]
]) set(x, y, z, "#fff4d6");

part("body", [0, 0, 0]);