fogón

← FantasíaObjeto 3Dfogon/torre-elfica

Torre élfica

de fogonCC010659 bloques
Torre élficaArrastrá para girarlo
// «Torre élfica» · gpt-6-sol (medium)
// An elegant slender elven tower: smooth white stone with graceful curves, tall narrow arched windows glowing soft teal, gold and leaf-green ornaments spiraling up, a pointed silver-green roof with a tiny gold spire, and climbing vines with white flowers around the base.

const cx = 24, cy = 24;
const stone = ["#c6d3cb", "#dce7de", "#eef4e9", "#f8faf0"];
const gold = "#d8b866";
const darkGold = "#a98748";
const leaf = ["#548c69", "#75a981", "#a1c590"];
const teal = ["#164c55", "#247e86", "#55d5ce", "#a5fff0"];

function disc(z, r, color) {
  for (let x = Math.floor(cx - r); x <= Math.ceil(cx + r); x++)
    for (let y = Math.floor(cy - r); y <= Math.ceil(cy + r); y++)
      if ((x - cx) ** 2 + (y - cy) ** 2 <= r * r)
        set(x, y, z, color);
}

// Rounded, moss-touched foundation.
disc(0, 10.8, "#77877d");
disc(1, 10.3, "#98a99b");
disc(2, 9.4, "#c0ccc0");
disc(3, 8.7, "#d9e3d7");
for (let z = 0; z <= 3; z++) {
  let r = [10.8, 10.3, 9.4, 8.7][z];
  for (let a = 0; a < Math.PI * 2; a += 0.095) {
    let x = Math.round(cx + r * Math.cos(a));
    let y = Math.round(cy + r * Math.sin(a));
    if (rand() < 0.31) set(x, y, z, z < 2 ? "#728e79" : "#aabca9");
  }
}

// Slightly tapered, softly curved solid tower.
function wallRadius(z) {
  return 7.65 + 0.55 * Math.sin((z - 3) * Math.PI / 27)
    + (z > 26 ? (z - 26) * 0.10 : 0);
}
for (let z = 4; z <= 31; z++) {
  const r = wallRadius(z);
  for (let x = 15; x <= 33; x++)
    for (let y = 15; y <= 33; y++) {
      let d = Math.hypot(x - cx, y - cy);
      if (d > r) continue;
      let c = d < r - 1.5 ? "#dce7de" :
        (y < cy - 2 || z > 26) ? stone[2] : stone[1];
      if (d > r - 1.4 && rand() < 0.075) c = stone[rand() < 0.6 ? 0 : 3];
      set(x, y, z, c);
    }
}

// Fine horizontal courses and a flared, crowned cornice.
for (let z of [5, 19, 30]) {
  let r = wallRadius(z) + 0.25;
  for (let a = 0; a < Math.PI * 2; a += 0.035)
    set(cx + r * Math.cos(a), cy + r * Math.sin(a), z,
        z === 30 ? "#e9efdf" : "#d1dbc9");
}
disc(32, 9.2, "#edf2e5");
disc(33, 10.1, "#e5eee0");
for (let a = 0; a < Math.PI * 2; a += 0.025) {
  set(cx + 9.9 * Math.cos(a), cy + 9.9 * Math.sin(a), 33, gold);
  set(cx + 9.4 * Math.cos(a), cy + 9.4 * Math.sin(a), 32, darkGold);
}

// Slender fluted columns, framing the front and flanking the back.
for (let x of [19, 29]) for (let y of [18, 30]) {
  cylinder(x, y, 4, 1.25, 27, "#eaf2e7");
  box(x - 1, y - 1, 5, x + 1, y + 1, 5, "#d5dfd3");
  box(x - 1, y - 1, 29, x + 1, y + 1, 30, "#f5f6e9");
  for (let z = 7; z <= 28; z++)
    set(x, y < 24 ? y - 1 : y + 1, z, z % 8 === 0 ? gold : "#f9faf0");
  set(x, y < 24 ? y - 2 : y + 2, 30, gold);
}

// Tall, pointed arched windows: dark recess, gold tracery, teal glow.
function windowWidth(z, bottom, top) {
  if (z < bottom || z > top) return -1;
  if (z === top) return 0;
  if (z === top - 1) return 1;
  return 2;
}
function frontWindow(bottom, top, back = false) {
  for (let z = bottom - 1; z <= top + 1; z++) {
    let w = windowWidth(z, bottom, top);
    let outer = w < 0 ? (z === bottom - 1 ? 2 : 0) : w + 1;
    for (let dx = -outer; dx <= outer; dx++) {
      let frame = w < 0 || Math.abs(dx) > w || z === bottom;
      let y0 = back ? 31 : 15;
      for (let depth = 0; depth <= 3; depth++) {
        let y = back ? y0 + depth : y0 + depth;
        set(cx + dx, y, z, frame
          ? (depth === 0 ? gold : "#aebbaf")
          : (depth < 2 ? "#315b61" : teal[2]));
      }
      if (!frame) set(cx + dx, back ? 34 : 14, z,
                       Math.abs(dx) === 2 ? teal[1] : teal[z % 3 === 0 ? 3 : 2]);
    }
  }
  // A diamond-shaped gold clasp between the two glass lancets.
  for (let z of [bottom + 3, bottom + 4])
    set(cx, back ? 34 : 14, z, "#f5d98b");
}
frontWindow(9, 17);
frontWindow(22, 29);
frontWindow(10, 17, true);
frontWindow(22, 29, true);

// Side-facing stained glass, narrower than the main windows.
for (let side of [-1, 1]) for (let [lo, hi] of [[11, 17], [23, 29]]) {
  for (let z = lo - 1; z <= hi; z++) {
    let w = z === hi ? 0 : (z === hi - 1 ? 1 : 2);
    for (let dy = -w - 1; dy <= w + 1; dy++) {
      let frame = Math.abs(dy) > w || z < lo;
      for (let depth = 0; depth < 3; depth++)
        set(cx + side * (7 + depth), cy + dy, z,
            frame ? (depth === 2 ? gold : "#c2d5c6") :
                    (depth === 2 ? teal[2] : "#2b6c72"));
      if (!frame)
        set(cx + side * 10, cy + dy, z,
            Math.abs(dy) === 2 ? teal[1] : teal[z % 3 === 0 ? 3 : 2]);
    }
  }
}

// A little golden sunburst between the two front windows.
set(24, 14, 19, "#fff0aa");
for (let [dx, dz] of [[-2, 0], [2, 0], [0, -2], [0, 2],
                       [-1, -1], [1, -1], [-1, 1], [1, 1]])
  set(24 + dx, 15, 19 + dz, gold);

// Silver-green pointed roof, with individual highlighted shingles.
for (let z = 34; z <= 43; z++) {
  let r = 10.1 - (z - 34) * 0.94;
  for (let x = Math.floor(cx - r); x <= Math.ceil(cx + r); x++)
    for (let y = Math.floor(cy - r); y <= Math.ceil(cy + r); y++) {
      if (Math.hypot(x - cx, y - cy) > r) continue;
      let c = (x + 2 * y + z) % 7 === 0 ? "#c1d3c1" :
              y < cy ? "#a9c2ad" : "#859f96";
      if (rand() < 0.08) c = "#d3ddc8";
      set(x, y, z, c);
    }
  for (let i = 0; i < 8; i++) {
    let a = i * Math.PI / 4;
    set(cx + r * Math.cos(a), cy + r * Math.sin(a), z,
        i % 2 ? "#d6e1ce" : "#718f82");
  }
}
for (let a = 0; a < Math.PI * 2; a += 0.065)
  set(cx + 10.1 * Math.cos(a), cy + 10.1 * Math.sin(a), 34, gold);
box(24, 24, 43, 24, 24, 45, gold);
set(24, 24, 46, "#fff1ab");
for (let a = 0; a < Math.PI * 2; a += Math.PI / 2)
  set(cx + 1.5 * Math.cos(a), cy + 1.5 * Math.sin(a), 43, "#e8d28a");

// Gold and leaf-green tendrils winding around the stonework.
for (let i = 0; i <= 470; i++) {
  let t = i / 470;
  let z = 5 + t * 25;
  let a = 1.05 + t * Math.PI * 4.2;
  let r = wallRadius(z) + 0.85;
  let x = cx + r * Math.cos(a), y = cy + r * Math.sin(a);
  set(x, y, z, i % 17 < 5 ? "#7ca87b" : gold);
  if (i % 39 === 0) {
    let leafA = a + 0.4;
    ellipsoid(cx + (r + 1.3) * Math.cos(leafA),
              cy + (r + 1.3) * Math.sin(leafA), z + 1,
              1.15, 1.15, 1.55, leaf[(i / 39) % 3 | 0]);
  }
}

// Climbing ivy at the foot, with broad leaves and small white blossoms.
for (let k = 0; k < 7; k++) {
  let a0 = k * Math.PI * 2 / 7 + 0.19;
  let height = 5 + (k % 3) * 2;
  let px = cx + 9.3 * Math.cos(a0), py = cy + 9.3 * Math.sin(a0);
  for (let j = 0; j <= height * 7; j++) {
    let z = j / 7;
    let a = a0 + z * 0.115;
    let r = 9.4 - z * 0.26;
    let x = cx + r * Math.cos(a), y = cy + r * Math.sin(a);
    line(px, py, Math.max(0, z - 0.15), x, y, z, 0, "#477c5e");
    px = x; py = y;
    if (j > 6 && j % 12 === 0) {
      let outward = a + (k % 2 ? 0.35 : -0.35);
      ellipsoid(cx + (r + 1.1) * Math.cos(outward),
                cy + (r + 1.1) * Math.sin(outward), z,
                1.2, 0.9, 0.7, leaf[(k + j) % 3]);
    }
  }
  let fa = a0 + height * 0.115;
  let fx = Math.round(cx + (8.6 - height * 0.13) * Math.cos(fa));
  let fy = Math.round(cy + (8.6 - height * 0.13) * Math.sin(fa));
  let fz = height;
  for (let [dx, dy, dz] of [[-1, 0, 0], [1, 0, 0], [0, -1, 0],
                              [0, 1, 0], [0, 0, 1]])
    set(fx + dx, fy + dy, fz + dz, "#fffaf0");
  set(fx, fy, fz, "#f4d979");
}

// A few tiny mossy stones and flowers nestled against the foundation.
for (let i = 0; i < 24; i++) {
  let a = rand() * Math.PI * 2, r = 10 + rand() * 1.1;
  let x = Math.round(cx + r * Math.cos(a));
  let y = Math.round(cy + r * Math.sin(a));
  set(x, y, 0, rand() < 0.55 ? "#719679" : "#a8b6a5");
  if (rand() < 0.3) {
    set(x, y, 1, "#fff9eb");
    set(x, y, 2, "#f2d386");
  }
}