fogón

← BásicoObjeto 3Dfogon/lampara-faro

Lámpara faro

de fogonCC018109 bloques
Lámpara faroArrastrá para girarlo
// «Lámpara faro» · gpt-6-sol (medium)
// Lighthouse lamp («Lámpara faro»).

const C = { x: 24, y: 24 };
const dist = (x, y) => Math.hypot(x - C.x, y - C.y);

function disk(z, r, color) {
  for (let x = Math.floor(C.x - r); x <= Math.ceil(C.x + r); x++)
    for (let y = Math.floor(C.y - r); y <= Math.ceil(C.y + r); y++)
      if (dist(x, y) <= r) set(x, y, z, color);
}

function ring(z, inner, outer, color) {
  for (let x = Math.floor(C.x - outer); x <= Math.ceil(C.x + outer); x++)
    for (let y = Math.floor(C.y - outer); y <= Math.ceil(C.y + outer); y++)
      if (dist(x, y) >= inner && dist(x, y) <= outer)
        set(x, y, z, color);
}

// Broad, low plinth: deep blue sides, brass edging, and a tiled deck.
for (const [z, r] of [[0, 17.3], [1, 19], [2, 20], [3, 20], [4, 18.8]])
  disk(z, r, z === 0 ? "#263f51" : z < 3 ? "#304e60" : "#345568");

ring(0, 15.7, 17.3, "#1b3547");
ring(1, 17.5, 19, "#203c50");
ring(2, 18.4, 20, "#d7ae59");
ring(3, 18.3, 20, "#284a5e");
ring(4, 16.8, 18.8, "#e7bb66");
disk(5, 16.5, "#e3d5aa");
ring(5, 14.7, 16.5, "#315669");
ring(5, 15.4, 16.2, "#e7bf70");
disk(6, 13.6, "#d5d1b7");
ring(6, 11.8, 13.6, "#f0e7cb");

for (let i = 0; i < 24; i++) {
  const a = i * Math.PI / 12;
  const x = Math.round(24 + 19.2 * Math.cos(a));
  const y = Math.round(24 + 19.2 * Math.sin(a));
  set(x, y, 2, i % 3 ? "#e3b961" : "#f3d783");
  if (i % 3 === 0) set(x, y, 1, "#142e40");
}
for (let i = 0; i < 20; i++) {
  const a = i * Math.PI / 10;
  const x = Math.round(24 + 15.6 * Math.cos(a));
  const y = Math.round(24 + 15.6 * Math.sin(a));
  set(x, y, 6, i % 2 ? "#f7e5a9" : "#456777");
}

// Stepped limestone footing.
disk(7, 11.3, "#bfc3af");
ring(7, 10, 11.3, "#f1e9d1");
disk(8, 10.3, "#d6d5bd");
ring(8, 9.1, 10.3, "#f7efdb");

for (let z = 9; z <= 27; z++) {
  const r = z <= 12 ? 8.9 : z <= 19 ? 8.2 : z <= 22 ? 8.5 : 8.3;
  for (let x = 15; x <= 33; x++)
    for (let y = 15; y <= 33; y++) {
      const d = dist(x, y);
      if (d > r) continue;
      let color;
      if (z <= 12) color = d > r - 1.4 ? "#d5d0bc" : "#b9b8aa";
      else if (z <= 14) color = d > r - 1.2 ? "#e9e3cb" : "#c7c3af";
      else if (z <= 19) color = "#ad5149";
      else if (z <= 22) color = "#d7d0bb";
      else if (z <= 25) color = "#bb5b50";
      else color = z === 26 ? "#e3d9bd" : "#a44942";

      if (z >= 15 && z <= 19 || z >= 23 && z <= 25) {
        if ((z + Math.floor(x / 3) + Math.floor(y / 3)) % 5 === 0)
          color = "#ca6658";
        if (d > r - 1.2 && y > 24 && rand() < 0.22)
          color = "#853f3e";
      }
      if (d > r - 1.3 && y < 24 && z <= 14 && rand() < 0.15)
        color = "#f5eed9";
      set(x, y, z, color);
    }
}

// Pale vertical fluting around the lower masonry and the white middle band.
for (let i = 0; i < 12; i++) {
  const a = i * Math.PI / 6;
  for (const [lo, hi, radius] of [[9, 14, 8.7], [20, 23, 8.25]]) {
    const x = Math.round(24 + radius * Math.cos(a));
    const y = Math.round(24 + radius * Math.sin(a));
    for (let z = lo; z <= hi; z++) {
      set(x, y, z, (i + z) % 5 === 0 ? "#f9eed5" : "#e5dfc9");
      if (z === lo || z === hi) set(x, y, z, "#faf0d8");
    }
  }
}
ring(14, 7.4, 8.5, "#e9e0c8");
ring(19, 7.2, 8.4, "#85433f");
ring(22, 7.4, 8.5, "#efe5ce");
ring(26, 7.3, 9.1, "#efe4c8");
ring(27, 8, 9.6, "#ab5149");

// Recessed, glowing doorway on the viewer-facing side.
box(26, 14, 9, 30, 15, 16, "#183446");
box(27, 13, 10, 29, 13, 15, "#172b3c");
box(27, 13, 12, 28, 13, 15, "#f6db79");
box(27, 13, 10, 29, 13, 11, "#334e57");
box(25, 14, 9, 25, 15, 16, "#edcb78");
box(31, 14, 9, 31, 16, 16, "#d3a95c");
box(26, 13, 17, 30, 15, 17, "#f4dc9c");
box(26, 14, 18, 30, 15, 18, "#9a4c42");
set(30, 12, 12, "#f6df96");

// Blue-and-gold balcony beneath the lantern.
disk(28, 11.5, "#27485b");
ring(28, 9.2, 11.5, "#d3a657");
disk(29, 12.2, "#28475a");
ring(29, 10, 12.2, "#e3bd6e");
disk(30, 10.7, "#213b4e");
ring(30, 9.6, 10.7, "#d7ad61");

// Lantern chamber. Gold-lit panes sit between chunky navy uprights.
for (let z = 31; z <= 35; z++) {
  disk(z, 10.2, "#203749");
  for (let x = 13; x <= 35; x++)
    for (let y = 13; y <= 35; y++) {
      const d = dist(x, y);
      if (d < 8.7 || d > 10.5) continue;
      const a = Math.atan2(y - 24, x - 24);
      const sector = Math.abs(Math.sin(a * 6));
      let color = sector < 0.24 ? "#294a5c" : "#b68d4b";
      if (sector >= 0.24 && z >= 32 && z <= 34)
        color = sector > 0.75 ? "#efd075" : "#d5a957";
      if (z === 31 || z === 35) color = "#25465b";
      set(x, y, z, color);
    }
}

for (let i = 0; i < 12; i++) {
  const a = i * Math.PI / 6;
  const x = Math.round(24 + 10.1 * Math.cos(a));
  const y = Math.round(24 + 10.1 * Math.sin(a));
  for (let z = 30; z <= 35; z++)
    set(x, y, z, z === 30 || z === 35 ? "#ecc977" : "#2b5063");
  set(x, y, 33, "#e5b85f");
}
ring(32, 9.7, 10.8, "#d6aa5b");
ring(35, 9.4, 11, "#e4bd70");
ring(36, 9.2, 11.8, "#253e50");

// Wide, layered red tile roof, narrowing to a little finial.
const roof = [
  [37, 13.3], [38, 13.6], [39, 12.4], [40, 10.8],
  [41, 8.6], [42, 6.3], [43, 3.3]
];
for (const [z, r] of roof) {
  for (let x = Math.floor(24 - r); x <= Math.ceil(24 + r); x++)
    for (let y = Math.floor(24 - r); y <= Math.ceil(24 + r); y++) {
      const d = dist(x, y);
      if (d > r) continue;
      const row = (Math.floor(x / 3) + Math.floor(y / 3) + z) % 4;
      let color = ["#bc514b", "#d46558", "#e47766", "#c75a51"][row];
      if (d > r - 1.35) color = z % 2 ? "#ad4543" : "#e07160";
      if (y > 25 && d > r - 2 && rand() < 0.38) color = "#a94341";
      if (y < 23 && rand() < 0.12) color = "#f0836d";
      set(x, y, z, color);
    }
}
ring(37, 11.5, 13.3, "#a94743");
ring(38, 11.8, 13.6, "#d26557");
ring(40, 9.4, 10.8, "#ad4945");
ring(42, 5.1, 6.3, "#aa4240");
box(23, 23, 44, 25, 25, 44, "#743c3a");
set(24, 24, 45, "#e2bf67");