fogón

← Antiguo y prehistoriaObjeto 3Dfogon/fuente-romana

Fuente romana

de fogonCC013286 bloques
Fuente romanaArrastrá para girarlo
// «Fuente romana» · gpt-6-sol (medium)
// A round Roman fountain: a wide marble basin on the ground filled with blue water, a central pedestal with a smaller upper bowl, and water falling from the upper bowl into the basin. Marble white with a weathered green-blue bronze fish spout in the middle.

const cx = 24, cy = 24;
const marble = ["#eee9dc", "#f8f5e9", "#d8d2c4", "#c3c1b6"];
const bronze = "#538d7c", bronzeLight = "#79aa91", bronzeDark = "#386d68";

function stone(z, top = false) {
  const n = rand();
  if (n < 0.055) return marble[3];
  if (n < 0.22) return marble[2];
  return top || n > 0.78 ? marble[1] : marble[0];
}

function roundLayer(z, outer, inner = 0, top = false) {
  for (let x = Math.ceil(cx - outer); x <= Math.floor(cx + outer); x++) {
    for (let y = Math.ceil(cy - outer); y <= Math.floor(cy + outer); y++) {
      const d = Math.hypot(x - cx, y - cy);
      if (d <= outer && d >= inner) set(x, y, z, stone(z, top));
    }
  }
}

// Broad, solid lower basin and its thick rolled marble lip.
roundLayer(0, 20);
roundLayer(1, 21);
roundLayer(2, 21);
roundLayer(3, 20.5);
for (let z = 4; z <= 6; z++) roundLayer(z, 21, 18.1);
roundLayer(7, 21.5, 17.9);
roundLayer(8, 22, 17.8, true);
roundLayer(9, 20.5, 18.2, true);

// Shallow carved bands on the outside of the basin.
for (let z of [2, 5]) {
  for (let x = 2; x <= 46; x++) {
    for (let y = 2; y <= 46; y++) {
      const d = Math.hypot(x - cx, y - cy);
      if (d > 20.1 && d < 21.2 && ((x + y) % 5 !== 0)) {
        set(x, y, z, z === 2 ? "#c7c3b8" : "#ddd8ca");
      }
    }
  }
}

// Chunky pedestal, with a broad foot and a capital beneath the upper bowl.
for (let z = 4; z <= 8; z++) roundLayer(z, z < 7 ? 7 : 6.3, 0, z === 8);
for (let z = 9; z <= 19; z++) roundLayer(z, 4.2);
roundLayer(20, 5.3);
roundLayer(21, 6.2);
roundLayer(22, 7.2, 0, true);

// Smaller, deep upper bowl.
roundLayer(23, 8.3);
roundLayer(24, 9.2);
roundLayer(25, 10.2, 6.8);
roundLayer(26, 11, 7.8);
roundLayer(27, 11, 8.1);
roundLayer(28, 10.7, 8.2);
roundLayer(29, 11.2, 8.7, true);

// Small bronze insets make the broad white rim legible from afar.
for (let i = 0; i < 12; i++) {
  const a = i * Math.PI / 6;
  const x = Math.round(cx + 20 * Math.cos(a));
  const y = Math.round(cy + 20 * Math.sin(a));
  set(x, y, 9, i % 3 === 0 ? bronzeLight : bronze);
}

// Friendly weathered-bronze fish: plump body, forward-facing head and spread fins.
ellipsoid(24, 24, 34, 3, 5, 3, bronze);
ellipsoid(24, 20, 35, 3.5, 3, 3, bronzeLight);
ellipsoid(24, 17, 34, 2.4, 2, 1.7, bronze);
box(23, 15, 33, 25, 16, 34, bronzeLight);
set(24, 14, 34, bronzeDark); // spout opening

ellipsoid(20, 24, 34, 2, 2.5, 1.2, bronzeDark);
ellipsoid(28, 24, 34, 2, 2.5, 1.2, bronzeDark);
line(19, 24, 34, 17, 27, 36, 1, bronzeLight);
line(29, 24, 34, 31, 27, 36, 1, bronzeLight);
line(24, 26, 36, 24, 29, 39, 1, bronzeDark);
line(24, 29, 38, 20, 32, 40, 1, bronzeLight);
line(24, 29, 38, 28, 32, 40, 1, bronzeLight);
line(24, 29, 38, 24, 32, 37, 1, bronze);

// Large eyes on the viewer-facing side, with tiny bright glints.
for (let x of [22, 26]) {
  set(x, 17, 37, "#193634");
  set(x, 16, 37, "#152b2d");
  set(x, 15, 38, "#e7f5e8");
}

// All water belongs to one color-animated part.
part("water", [24, 24, 0]);

// Blue surfaces sit inside the stone without covering the pedestal.
for (let z of [6, 7]) {
  for (let x = 7; x <= 41; x++) {
    for (let y = 7; y <= 41; y++) {
      if (Math.hypot(x - cx, y - cy) < 17.7 && !get(x, y, z)) {
        set(x, y, z, z === 7 ? "#65bce4" : "#398fc7");
      }
    }
  }
}
for (let x = 17; x <= 31; x++) {
  for (let y = 17; y <= 31; y++) {
    if (Math.hypot(x - cx, y - cy) < 7.7) {
      for (let z of [26, 27]) {
        if (!get(x, y, z)) set(x, y, z, "#80d2eb");
      }
    }
  }
}

// The fish pours into its bowl; four bold streams spill into the lower basin.
line(24, 14, 34, 24, 15, 31, 0, "#e8fbfa");
line(24, 15, 31, 24, 18, 27, 0, "#8edbea");

for (let i = 0; i < 4; i++) {
  const a = i * Math.PI / 2;
  const dx = Math.sin(a), dy = -Math.cos(a);
  const p = (r, z) => [Math.round(cx + dx * r), Math.round(cy + dy * r), z];
  const radii = [10.5, 11, 12, 13, 14.5, 15.5];
  const heights = [28, 25, 21, 16, 11, 8];
  for (let j = 0; j < radii.length - 1; j++) {
    line(...p(radii[j], heights[j]), ...p(radii[j + 1], heights[j + 1]),
      j % 2 ? 0 : 0.7, j % 2 ? "#d8f6f5" : "#6ac9e9");
  }
  const [sx, sy] = p(15.5, 7);
  for (let t = -2; t <= 2; t++) {
    const x = sx + Math.round(dy * t);
    const y = sy - Math.round(dx * t);
    if (!get(x, y, 8)) set(x, y, 8, "#d8f6f5");
  }
}

animate("water", {
  type: "colors",
  palette: ["#78d3ed", "#3f9fd5", "#e8faff"],
  pattern: "wave",
  glow: 0.3
});