fogón

← MedievalObjeto 3Dfogon/torre-de-vigia

Torre de vigía

de fogonCC07019 bloques
Torre de vigíaArrastrá para girarlo
// «Torre de vigía» · gpt-6-sol (medium)
// A tall wooden watchtower: four thick log legs with diagonal cross braces rising to a square plank platform with a log railing, topped by a small pointed thatched roof on four posts, a wooden ladder climbing one side, and a small red pennant on a pole at the very top. Much taller than wide.

const timber = "#573824";
const timberLight = "#795032";
const timberDark = "#39271e";
const iron = "#282b2b";
const stone = ["#827e71", "#999386", "#6d6b62"];
const straw = ["#bc904f", "#cba462", "#a77c42", "#d5b370"];

function log(x0, y0, z0, x1, y1, z1) {
  box(x0, y0, z0, x1, y1, z1, timber);
  line(x0, y0, z0, x1, y1, z1, 0, timberLight);
}

// Four stone footings and heavy upright logs.
for (const x of [14, 33]) {
  for (const y of [14, 33]) {
    box(x - 2, y - 2, 0, x + 2, y + 2, 2, stone[0]);
    for (let i = 0; i < 14; i++) {
      set(x - 2 + Math.floor(rand() * 5),
          y - 2 + Math.floor(rand() * 5),
          Math.floor(rand() * 3),
          rand() < 0.18 ? "#69715a" : stone[1 + Math.floor(rand() * 2)]);
    }

    box(x - 1, y - 1, 2, x + 1, y + 1, 30, timber);
    box(x - 1, y - 1, 3, x - 1, y - 1, 29, timberLight);
    for (const z of [5, 17, 28]) {
      box(x - 1, y - 1, z, x + 1, y + 1, z, iron);
      set(x, y - 2, z, "#9d9375");
    }
  }
}

// Diagonal cross-bracing on all four open sides.
for (const y of [14, 33]) {
  line(15, y, 7, 32, y, 24, 1, timberDark);
  line(32, y, 7, 15, y, 24, 1, timberLight);
  line(15, y, 25, 32, y, 8, 0, timber);
}
for (const x of [14, 33]) {
  line(x, 15, 8, x, 32, 25, 1, timberDark);
  line(x, 32, 8, x, 15, 25, 1, timberLight);
}

// Stout beams immediately beneath the lookout floor.
for (const y of [13, 24, 34]) log(12, y, 28, 36, y, 28);
for (const x of [13, 24, 34]) log(x, 12, 28, x, 36, 28);

// Broad plank platform, with individually readable boards.
box(10, 10, 29, 38, 38, 29, timberDark);
for (let y = 10; y <= 38; y += 2) {
  box(10, y, 30, 38, Math.min(y + 1, 38), 30,
      y % 4 === 2 ? "#a57848" : "#93673e");
  for (let x = 12; x <= 37; x += 8) {
    set(x, y, 30, "#6e492f");
  }
}
for (const y of [10, 38]) box(10, y, 29, 38, y, 31, timberDark);
for (const x of [10, 38]) box(x, 10, 29, x, 38, 31, timberDark);
for (let x = 13; x <= 36; x += 5) {
  for (const y of [9, 39]) set(x, y, 30, "#a49a78");
}

// Railing, leaving an opening at the front for the ladder.
for (const x of [12, 18, 30, 36]) {
  box(x, 11, 31, x + 1, 12, 35, timber);
  box(x, 36, 31, x + 1, 37, 35, timber);
}
for (const y of [18, 25, 32]) {
  box(11, y, 31, 12, y + 1, 35, timber);
  box(36, y, 31, 37, y + 1, 35, timber);
}
for (const z of [32, 35]) {
  for (const y of [11, 37]) {
    box(13, y, z, 20, y, z, timberLight);
    box(28, y, z, 35, y, z, timberLight);
    if (y === 37) box(21, y, z, 27, y, z, timberLight);
  }
  for (const x of [11, 37]) box(x, 13, z, x, 35, z, timberLight);
}

// Four roof-supporting posts, above the railing.
for (const x of [13, 35]) {
  for (const y of [13, 35]) {
    box(x - 1, y - 1, 31, x + 1, y + 1, 37, timberDark);
    box(x - 1, y - 1, 33, x - 1, y - 1, 37, timberLight);
    box(x - 1, y - 1, 35, x + 1, y + 1, 35, iron);
  }
}

// Sloping ladder on the front, anchored at the platform opening.
for (let z = 1; z <= 31; z++) {
  const y = 5 + Math.round(z * 6 / 31);
  for (const x of [21, 27]) {
    set(x, y, z, timberDark);
    set(x, y - 1, z, timberLight);
  }
  if (z >= 2 && z <= 29 && z % 3 === 2) {
    box(22, y - 1, z, 26, y, z, "#a77a49");
    set(23, y - 1, z, "#c09257");
  }
}

// Dark rafters under the overhanging thatch.
for (const y of [11, 24, 37]) log(10, y, 36, 38, y, 36);
for (const x of [11, 24, 37]) log(x, 10, 36, x, 38, 36);

// Layered, pointed thatched roof.
const roofLayers = [
  [37, 9, 39], [38, 11, 37], [39, 14, 34],
  [40, 17, 31], [41, 20, 28], [42, 22, 26], [43, 24, 24]
];
for (const [z, lo, hi] of roofLayers) {
  for (let x = lo; x <= hi; x++) {
    for (let y = lo; y <= hi; y++) {
      const edge = Math.min(x - lo, hi - x, y - lo, hi - y);
      let color = straw[(Math.floor(x / 4) + Math.floor(y / 5) + z) % straw.length];
      if (edge === 0 && rand() < 0.55) color = "#957044";
      if (rand() < 0.09) color = "#dfbb76";
      set(x, y, z, color);
      if (edge === 0 && z < 41 && rand() < 0.25) {
        set(x, y, z - 1, "#aa7d42");
      }
    }
  }
}

// Finial and flagpole.
box(24, 24, 43, 24, 24, 45, iron);
set(24, 24, 45, "#d6b966");

// The pennant turns gently around the pole.
part("pennant", [24, 24, 44]);
for (let x = 25; x <= 33; x++) {
  const tip = x >= 31;
  set(x, 24, 44, x % 3 === 0 ? "#911f2a" : "#b62c35");
  if (!tip) set(x, 24, 43, "#801f2a");
}
for (let x = 25; x <= 29; x++) set(x, 23, 44, "#cc994c");
set(28, 23, 43, "#e3bb64");
set(29, 23, 43, "#e3bb64");
animate("pennant", { type: "swing", axis: "z", speed: 3, amplitude: 0.3 });
part("body", [24, 24, 0]);