fogón

← MedievalObjeto 3Dfogon/catapulta

Catapulta

de fogonCC03553 bloques
CatapultaArrastrá para girarlo
// «Catapulta» · gpt-6-sol (medium)
// A wooden siege catapult (mangonel) in 3/4 view: a low rectangular base frame of thick dark brown beams (about 30 long, 16 wide) on four chunky spoked wooden wheels at the corners. Near the front of the frame a tall upright wooden gantry: two vertical posts, one on each side, joined at the top by a thick horizontal crossbar about 18 blocks above the ground. A single long straight throwing arm (a beam 3 blocks thick) pivots on an axle across the back half of the frame and rises diagonally forward-up at about 45 degrees to lean against the crossbar, its top end sticking up above the crossbar and holding a big round wooden cup containing a grey stone ball. A twisted rope bundle around the axle. The arm, crossbar and cup must be clearly separate and visible against the sky.

const wood = "#60391f", woodLight = "#86532d", woodDark = "#422718";
const edge = "#a4713c", iron = "#25282b", ironLight = "#55595a";
const rope = "#b79a67", gold = "#c59a49";

function beam(x0, y0, z0, x1, y1, z1) {
  box(x0, y0, z0, x1, y1, z1, wood);
  box(x0, y0, z1, x1, y1, z1, woodLight);
}

// Four solid, spoked wheels. Their rims stand on z = 0.
for (const x0 of [10, 35]) {
  for (const yc of [11, 37]) {
    for (let x = x0; x <= x0 + 3; x++) {
      for (let y = yc - 5; y <= yc + 5; y++) {
        for (let z = 0; z <= 10; z++) {
          const d = Math.hypot(y - yc, z - 5);
          if (d >= 3.5 && d <= 5.15)
            set(x, y, z, z >= 5 ? woodLight : woodDark);
        }
      }
    }
    for (let i = 0; i < 8; i++) {
      const a = i * Math.PI / 4;
      line(x0 + 1, yc, 5,
           x0 + 1, yc + Math.round(4.3 * Math.cos(a)),
           5 + Math.round(4.3 * Math.sin(a)), 0, woodLight);
      line(x0 + 2, yc, 5,
           x0 + 2, yc + Math.round(4.3 * Math.cos(a)),
           5 + Math.round(4.3 * Math.sin(a)), 0, wood);
    }
    for (let y = yc - 5; y <= yc + 5; y++) {
      for (let z = 0; z <= 10; z++) {
        const d = Math.hypot(y - yc, z - 5);
        if (d >= 4.55 && d <= 5.15) {
          set(x0 - 1, y, z, iron);
          set(x0 + 4, y, z, iron);
        }
      }
    }
    box(x0 - 1, yc - 1, 4, x0 + 4, yc + 1, 6, woodDark);
    set(x0 - 1, yc, 5, ironLight);
    set(x0 + 4, yc, 5, ironLight);
  }
}

for (const y of [11, 37]) {
  box(13, y, 5, 35, y, 5, iron);
}

// Low rectangular chassis, with heavy rails and cross-ties.
beam(16, 10, 5, 18, 38, 7);
beam(30, 10, 5, 32, 38, 7);
for (const y of [10, 20, 29, 36]) beam(16, y, 5, 32, y + 2, 7);
for (const y of [12, 23, 33]) {
  box(16, y, 6, 16, y + 1, 7, iron);
  box(32, y, 6, 32, y + 1, 7, iron);
  set(16, y, 7, ironLight);
  set(32, y, 7, ironLight);
}

// Upright gantry and its splayed braces.
for (const x of [16, 30]) {
  beam(x, 17, 8, x + 2, 19, 22);
  line(x + 1, 25, 8, x + 1, 18, 18, 1, woodDark);
  line(x + 1, 24, 9, x + 1, 18, 17, 0, woodLight);
  box(x, 17, 19, x + 2, 19, 20, iron);
  set(x, 17, 20, ironLight);
}
beam(16, 18, 21, 32, 20, 23);
box(16, 18, 21, 16, 20, 23, iron);
box(32, 18, 21, 32, 20, 23, iron);
for (const x of [20, 28]) {
  set(x, 18, 22, gold);
  set(x, 18, 23, ironLight);
}

// Rear bearing blocks and the axle across the frame.
for (const x of [16, 30]) {
  beam(x, 29, 8, x + 2, 33, 12);
  box(x, 29, 11, x + 2, 33, 11, iron);
}
cylinder(15, 31, 12, 1, 19, iron, "x");
for (const x of [15, 34]) {
  box(x, 30, 11, x, 32, 13, ironLight);
  set(x, 31, 12, gold);
}

// Thick, visibly twisted skeins of rope around either side of the pivot.
for (const start of [19, 26]) {
  for (let j = 0; j < 30; j++) {
    const x = start + j / 10;
    const a = j * Math.PI * 0.75;
    set(x, 31 + 2 * Math.cos(a), 12 + 2 * Math.sin(a),
        j % 4 === 0 ? "#dfc58b" : rope);
  }
}

// Small heraldic plaque on the near side of the frame.
box(15, 24, 8, 15, 28, 12, gold);
box(14, 25, 9, 14, 27, 11, "#8d2934");
set(14, 26, 11, gold);
set(14, 26, 10, gold);
set(14, 25, 10, gold);
set(14, 27, 10, gold);

// The arm, cup, and stone all swing together around the rear axle.
part("throwing arm", [24, 31, 12]);

for (let t = 0; t <= 21; t++) {
  const y = 31 - t, z = 12 + t;
  box(23, y - 1, z - 1, 25, y + 1, z + 1,
      t % 6 === 2 ? woodLight : wood);
  if (t % 4 === 0) {
    set(23, y, z + 1, edge);
    set(25, y, z + 1, woodLight);
  }
}
for (const t of [4, 13, 19]) {
  const y = 31 - t, z = 12 + t;
  box(22, y - 1, z - 1, 22, y + 1, z + 1, iron);
  box(26, y - 1, z - 1, 26, y + 1, z + 1, iron);
  set(22, y, z, ironLight);
  set(26, y, z, ironLight);
}

// Deep wooden throwing cup, with a raised circular lip.
ellipsoid(24, 9, 33, 4, 4, 2, woodDark);
ellipsoid(24, 9, 34, 3.5, 3.5, 1, woodLight);
for (let x = 19; x <= 29; x++) {
  for (let y = 4; y <= 14; y++) {
    const d = Math.hypot(x - 24, y - 9);
    if (d >= 3.2 && d <= 4.35) {
      set(x, y, 35, woodLight);
      if (d >= 3.7) set(x, y, 36, edge);
    }
  }
}
sphere(24, 9, 36, 2.4, "#777977");
for (const p of [[23, 7, 37], [24, 8, 38], [25, 9, 38], [22, 9, 36]])
  set(...p, "#adb0a9");
for (const p of [[26, 10, 35], [25, 11, 36]])
  set(...p, "#555957");

part("body");
animate("throwing arm", { type: "swing", axis: "x", speed: 2, amplitude: 0.5 });