fogón

← MedievalObjeto 3Dfogon/pozo-de-los-deseos

Pozo de los deseos

de fogonCC09952 bloques
Pozo de los deseosArrastrá para girarlo
// «Pozo de los deseos» · gpt-6-sol (medium)
// A round medieval wishing well: a ring of grey stone blocks with a dark water surface inside with a few gold coins glinting, two wooden posts holding a small red tile roof, a wooden crank with rope and a wooden bucket hanging down.

const stone = ["#908b80", "#a39d90", "#b5ad9e", "#77756e"];
const darkStone = "#66645e";
const wood = "#493024";
const woodLight = "#715038";
const iron = "#292a2b";
const gold = "#e8bc57";

// Broad, uneven stone footing.
for (let x = 9; x <= 39; x++) for (let y = 9; y <= 39; y++) {
  const r = Math.hypot(x - 24, y - 24);
  if (r <= 14.2 && r > 13.6 && rand() < 0.18) continue;
  if (r <= 14.2) for (let z = 0; z <= 1; z++)
    set(x, y, z, rand() < 0.16 ? "#77756e" : "#88867d");
}

// Coursed, individually shaded stonework around the hollow well.
for (let z = 2; z <= 11; z++) {
  for (let x = 11; x <= 37; x++) for (let y = 11; y <= 37; y++) {
    const r = Math.hypot(x - 24, y - 24);
    if (r < 8.5 || r > 12.7) continue;
    const angle = (Math.atan2(y - 24, x - 24) + Math.PI) / (2 * Math.PI);
    const course = Math.floor((z - 2) / 3);
    const joint = (angle * 18 + (course % 2) * 0.5) % 1;
    const seam = z === 2 || z === 5 || z === 8 || joint < 0.055;
    let color = seam ? darkStone : stone[Math.floor(rand() * stone.length)];
    if (!seam && rand() < 0.027 && y > 22) color = "#727b60";
    set(x, y, z, color);
  }
}

// Thick, pale coping stones, with darker joints between them.
for (let x = 10; x <= 38; x++) for (let y = 10; y <= 38; y++) {
  const r = Math.hypot(x - 24, y - 24);
  if (r < 8.3 || r > 13.25) continue;
  const angle = (Math.atan2(y - 24, x - 24) + Math.PI) / (2 * Math.PI);
  const joint = (angle * 16) % 1 < 0.045;
  set(x, y, 12, joint ? "#77736a" : rand() < 0.4 ? "#c3b9a8" : "#aaa397");
  if (r > 12.4) set(x, y, 11, "#817e75");
}

// Still, deep water and a handful of glinting coins.
for (let x = 16; x <= 32; x++) for (let y = 16; y <= 32; y++) {
  if (Math.hypot(x - 24, y - 24) > 8.3) continue;
  set(x, y, 9, rand() < 0.16 ? "#354c53" : "#263b43");
  if (rand() < 0.07) set(x, y, 10, "#4c666a");
}
for (const [x, y] of [[19,19],[21,17],[27,18],[30,22],[17,25],[29,28],[20,29]]) {
  set(x, y, 10, "#a77a32");
  set(x + 1, y, 10, gold);
  if (rand() < 0.5) set(x, y + 1, 10, "#f4d780");
}

// Two hefty posts, standing just outside the stone ring.
for (const x of [11, 37]) {
  box(x - 1, 23, 2, x + 1, 26, 31, wood);
  box(x - 1, 23, 4, x - 1, 23, 30, woodLight);
  box(x - 1, 23, 14, x + 1, 26, 15, iron);
  box(x - 1, 23, 25, x + 1, 26, 26, iron);
  for (const z of [14, 25]) {
    set(x - 1, 22, z, "#aea69a");
    set(x + 1, 22, z, "#aea69a");
  }
  box(x - 2, 22, 29, x + 2, 27, 30, woodLight);
}

// Crossbeam, with little projecting timber ends.
box(10, 23, 30, 38, 26, 32, wood);
box(10, 23, 32, 38, 23, 32, woodLight);
for (const x of [11, 37]) {
  line(x, 23, 25, x < 24 ? x + 5 : x - 5, 23, 30, 1, woodLight);
}

// Cream-plaster front gable, framed in dark timber.
for (let x = 14; x <= 34; x++) {
  const roofHeight = 39 - Math.ceil(Math.abs(x - 24) * 0.48);
  for (let z = 32; z < roofHeight - 1; z++) set(x, 10, z, "#e5d6b7");
}
line(14, 10, 32, 24, 10, 38, 1, wood);
line(24, 10, 38, 34, 10, 32, 1, wood);
box(14, 9, 31, 34, 10, 32, wood);

// A tiny royal-blue heraldic shield on the front gable.
box(22, 8, 33, 26, 8, 35, gold);
box(23, 7, 33, 25, 7, 35, "#244673");
set(24, 6, 35, gold);
set(24, 6, 34, "#a43c38");
set(24, 7, 32, gold);

// Solid pitched red-clay roof; staggered tile joints on both slopes.
for (let x = 6; x <= 42; x++) for (let y = 8; y <= 40; y++) {
  const top = 39 - Math.ceil(Math.abs(x - 24) * 0.48);
  const row = Math.floor(Math.abs(x - 24) / 3);
  set(x, y, top - 2, "#542d27");
  set(x, y, top - 1, "#74372c");

  const seam = (y + (row % 2) * 2) % 5 === 0;
  const shade = rand();
  const tile = seam ? "#79372d"
    : shade < 0.18 ? "#a44334"
    : shade < 0.7 ? "#bb5940" : "#ce7050";
  set(x, y, top, tile);
  if (Math.abs(x - 24) % 3 === 2)
    set(x, y, top - 1, "#d27854");
}
// Ridge tiles and dark carved fascia at both roof ends.
box(23, 7, 39, 25, 41, 39, "#8e4032");
for (const y of [8, 40]) {
  line(6, y, 30, 24, y, 39, 0, wood);
  line(24, y, 39, 42, y, 30, 0, wood);
}

// Wooden winding drum beneath the roof, rope descending to the bucket.
cylinder(20, 24, 29, 2, 9, woodLight, "x");
box(19, 21, 28, 20, 27, 30, iron);
box(28, 21, 28, 29, 27, 30, iron);
for (let z = 17; z <= 28; z++) {
  set(24, 23, z, "#be9866");
  if (z % 3 === 0) set(25, 23, z, "#e0bf85");
}

// Tapered wooden bucket: its dark, open mouth remains visible.
for (let z = 10; z <= 16; z++) {
  const radius = z < 13 ? 3.2 : 4.1;
  for (let x = 19; x <= 29; x++) for (let y = 19; y <= 29; y++) {
    const d = Math.hypot(x - 24, y - 24);
    if (d > radius) continue;
    const wall = d >= radius - 1.25;
    if (z === 10 || wall) {
      let c = y <= 23 ? "#906644" : "#68452f";
      if (x % 2 === 0 && wall) c = y <= 23 ? "#a7794f" : "#795137";
      set(x, y, z, c);
    }
  }
}
for (let x = 19; x <= 29; x++) for (let y = 19; y <= 29; y++) {
  const d = Math.hypot(x - 24, y - 24);
  if (d >= 3 && d <= 4.4) {
    for (const z of [11, 15]) set(x, y, z, iron);
    set(x, y, 17, "#b68554");
  } else if (d < 3) {
    set(x, y, 16, "#302920");
  }
}
for (const x of [20, 28]) {
  set(x, 24, 16, "#bcb2a0");
  set(x, 24, 17, iron);
}
line(20, 24, 17, 22, 24, 19, 0, iron);
line(22, 24, 19, 26, 24, 19, 0, iron);
line(26, 24, 19, 28, 24, 17, 0, iron);
set(24, 24, 19, "#c8a878");

// The exterior crank is the only moving piece: axle, bent arm and grip.
part("crank", [37, 24, 26]);
cylinder(36, 24, 26, 1, 8, woodLight, "x");
box(39, 23, 25, 40, 25, 27, iron);
line(43, 24, 26, 43, 24, 31, 1, iron);
cylinder(43, 24, 31, 1, 3, woodLight, "x");
set(45, 24, 31, "#c99a60");
animate("crank", { type: "spin", axis: "x", speed: 1 });
part("body", [24, 24, 0]);