fogón

← BásicoObjeto 3Dfogon/escalera-caracol

Escalera caracol

de fogonCC05095 bloques
Escalera caracolArrastrá para girarlo
// «Escalera caracol» · gpt-6-sol (medium)
// Spiral staircase («Escalera caracol»).

// Spiral staircase: pale stone ground ring, dark central column, and warm wooden steps.
const cx = 24, cy = 24;
const steps = 27;
const start = -1.10;
const turn = 0.32;
const rise = 1.22;
const outerR = 13;

// Thin, slightly irregular stone circle on the ground.
for (let x = 4; x <= 44; x++) {
  for (let y = 7; y <= 41; y++) {
    const d = Math.hypot((x - cx) / 19.2, (y - cy) / 16.1);
    if (d > 0.905 && d < 1.025) {
      set(x, y, 0, rand() < 0.14 ? "#859b98" : d > 0.975 ? "#a6b8b2" : "#c0cdc6");
      if (d > 0.975 && rand() < 0.28) set(x, y, 1, "#d4dcd3");
    }
  }
}

// Square, layered base and substantial blue-black central newel.
box(20, 20, 0, 28, 28, 1, "#263b3c");
box(21, 21, 2, 27, 27, 3, "#355454");
box(22, 22, 4, 26, 26, 39, "#193840");
box(22, 22, 4, 22, 26, 39, "#315860");
box(23, 22, 4, 25, 22, 39, "#284b52");
box(26, 23, 4, 26, 26, 39, "#102d35");
for (let z = 5; z < 39; z += 3) {
  box(21, 21, z, 27, 27, z, z % 2 ? "#31535a" : "#23464e");
  box(22, 21, z + 1, 25, 21, z + 1, "#41636a");
}
box(21, 21, 39, 27, 27, 40, "#21434b");
box(22, 22, 41, 26, 26, 41, "#34575c");
box(23, 23, 42, 25, 25, 42, "#b88744");

function point(a, r) {
  return [Math.round(cx + Math.cos(a) * r), Math.round(cy + Math.sin(a) * r)];
}
function height(i) {
  return Math.round(5 + i * rise);
}
function angleDiff(a, b) {
  return Math.atan2(Math.sin(a - b), Math.cos(a - b));
}

// Solid wedge-shaped treads. Each has a shaded underside, golden top and dark outer lip.
for (let i = 0; i < steps; i++) {
  const a = start + i * turn;
  const z = height(i);
  const minX = Math.floor(cx - outerR - 1), maxX = Math.ceil(cx + outerR + 1);
  const minY = Math.floor(cy - outerR - 1), maxY = Math.ceil(cy + outerR + 1);

  for (let x = minX; x <= maxX; x++) {
    for (let y = minY; y <= maxY; y++) {
      const r = Math.hypot(x - cx, y - cy);
      const off = angleDiff(Math.atan2(y - cy, x - cx), a);
      if (r < 2.7 || r > outerR || Math.abs(off) > 0.183) continue;

      set(x, y, z - 2, "#654728");
      set(x, y, z - 1, r > 11.6 ? "#925e2b" : "#ae7132");
      let wood = rand() < 0.13 ? "#d59546" : rand() < 0.19 ? "#f5bf69" : "#e9ad55";
      if (off < -0.12) wood = "#f4c477";
      set(x, y, z, wood);
      if (r > 12.1) set(x, y, z - 1, "#9c632c");
    }
  }

  // A chunky bracket beneath each outer end.
  const [bx, by] = point(a, 9.5);
  box(bx - 1, by - 1, z - 3, bx + 1, by + 1, z - 2, "#694729");
  const [ix, iy] = point(a, 4.4);
  line(ix, iy, z - 3, bx, by, z - 3, 0, "#80552e");
}

// Outer balusters: dark teal ironwork with pale edges and warm wooden caps.
for (let i = 0; i < steps; i += 3) {
  const a = start + i * turn;
  const [x, y] = point(a, 12.7);
  const z = height(i);
  box(x, y, z + 1, x + 1, y + 1, z + 7, "#193940");
  box(x, y, z + 2, x, y, z + 6, "#365860");
  box(x, y, z + 7, x + 1, y + 1, z + 8, "#c4873c");
  set(x, y, z + 9, "#f1bf6a");
}
// A last post at the upper landing.
{
  const a = start + (steps - 1) * turn;
  const [x, y] = point(a, 12.7);
  const z = height(steps - 1);
  box(x, y, z + 1, x + 1, y + 1, z + 8, "#24454b");
  box(x, y, z + 8, x + 1, y + 1, z + 8, "#d59849");
}

// Continuous stepped handrail and a lower cross rail following the spiral.
for (let i = 0; i < steps - 1; i++) {
  const a = start + i * turn;
  const b = a + turn;
  const [x0, y0] = point(a, 12.8);
  const [x1, y1] = point(b, 12.8);
  const z0 = height(i), z1 = height(i + 1);

  line(x0, y0, z0 + 8, x1, y1, z1 + 8, 0, "#b77b37");
  line(x0, y0, z0 + 9, x1, y1, z1 + 9, 0, "#edb65e");
  line(x0, y0, z0 + 4, x1, y1, z1 + 4, 0, "#a87134");

  // Short upright spindle between the rails on alternate steps.
  if (i % 2 === 1) {
    const [sx, sy] = point(a + turn * 0.5, 12.8);
    const sz = Math.round((z0 + z1) / 2);
    box(sx, sy, sz + 4, sx, sy, sz + 8, "#24434a");
  }
}

// Visible golden nosing at the first and last steps.
for (const i of [0, steps - 1]) {
  const a = start + i * turn;
  const z = height(i);
  for (let r = 5; r <= 12; r++) {
    const [x, y] = point(a + 0.16, r);
    set(x, y, z, "#f4c476");
  }
}