fogón

← Antiguo y prehistoriaObjeto 3Dfogon/volcan

Volcán

de fogonCC020773 bloques
VolcánArrastrá para girarlo
// «Volcán» · gpt-6-sol (medium)
// A cartoon volcano: a wide cone of dark brown and charcoal rock with rough layered sides, a crater on top glowing with bright orange lava, and a few streams of lava running down the sides. A puff of grey smoke above the crater.

const cx = 24, cy = 24;
const rock = ["#393735", "#49413a", "#5b4a3c", "#6b5542", "#786049"];

function radiusAt(z, a) {
  return 20.3 - 0.435 * z
    + 0.65 * Math.sin(5 * a + 0.39 * z)
    + 0.38 * Math.sin(9 * a - 0.27 * z);
}

// A solid, uneven cone with broad horizontal bands of volcanic rock.
for (let z = 0; z <= 29; z++) {
  for (let x = 3; x <= 45; x++) {
    for (let y = 3; y <= 45; y++) {
      const dx = x - cx, dy = y - cy;
      const r = Math.hypot(dx, dy);
      const a = Math.atan2(dx, -dy);
      const edge = radiusAt(z, a);
      if (r > edge || (z >= 26 && r < 4.65)) continue;

      const band = Math.sin(z * 1.13 + a * 1.6);
      let shade = band > 0.55 ? 3 : band < -0.55 ? 1 : 2;
      if (z < 5) shade--;
      if (r > edge - 2 && rand() < 0.19) shade += rand() < 0.5 ? -1 : 1;
      shade = Math.max(0, Math.min(4, shade));
      set(x, y, z, rock[shade]);
    }
  }
}

// Chunky, broken rim around the open crater.
for (let z = 30; z <= 32; z++) {
  for (let x = 15; x <= 33; x++) {
    for (let y = 15; y <= 33; y++) {
      const dx = x - cx, dy = y - cy;
      const a = Math.atan2(dx, -dy);
      const r = Math.hypot(dx, dy);
      const outer = (z === 30 ? 8.15 : z === 31 ? 7.65 : 7.1)
        + 0.5 * Math.sin(5 * a + 0.7);
      if (r >= 4.7 && r <= outer &&
          (z < 32 || Math.sin(7 * a + 2) > -0.25)) {
        set(x, y, z, rand() < 0.24 ? "#786049" : "#49413a");
      }
    }
  }
}

// A few dark boulders anchor the wide base.
for (const [x, y, rx, ry, rz] of [
  [9, 17, 3, 3, 3], [37, 12, 3, 2, 3],
  [11, 34, 3, 3, 2], [39, 32, 3, 3, 3]
]) {
  ellipsoid(x, y, 1, rx, ry, rz, "#393735");
}

// The crater pool and all three downhill streams glow together.
part("lava", [cx, cy, 28]);
for (let z = 26; z <= 29; z++) {
  const r = z === 29 ? 4.75 : 4.9;
  for (let x = 19; x <= 29; x++) {
    for (let y = 19; y <= 29; y++) {
      if (Math.hypot(x - cx, y - cy) <= r) {
        set(x, y, z, rand() < 0.22 ? "#ffca48" : "#f66b20");
      }
    }
  }
}

const streams = [
  { angle: -0.42, bottom: 2, width: 1.75 },
  { angle:  0.79, bottom: 7, width: 1.55 },
  { angle: -1.19, bottom: 12, width: 1.25 }
];
for (const s of streams) {
  for (let z = s.bottom; z <= 31; z++) {
    const a = s.angle + 0.07 * Math.sin(z * 0.53 + s.angle * 4);
    const surface = z > 29 ? (z === 31 ? 7.6 : 8.1) : radiusAt(z, a);
    for (let x = 3; x <= 45; x++) {
      for (let y = 3; y <= 45; y++) {
        const dx = x - cx, dy = y - cy;
        const r = Math.hypot(dx, dy);
        const angle = Math.atan2(dx, -dy);
        let difference = angle - a;
        while (difference > Math.PI) difference -= 2 * Math.PI;
        while (difference < -Math.PI) difference += 2 * Math.PI;
        if (Math.abs(difference) * r <= s.width &&
            r >= surface - 0.7 && r <= surface + 1.1) {
          set(x, y, z, rand() < 0.23 ? "#ffca48" : "#ee5720");
        }
      }
    }
  }
}
animate("lava", {
  type: "colors", palette: ["#a52e19", "#f26a1e", "#ffd04a"],
  pattern: "wave", glow: 0.9
});

// A soft, lumpy puff rises clear of the crater.
part("smoke", [25, 23, 37]);
sphere(24, 23, 35, 2, "#747570");
sphere(25, 23, 38, 3, "#898b86");
sphere(27, 23, 41, 3, "#9b9d98");
sphere(24, 22, 43, 3, "#aaa9a2");
sphere(29, 22, 43, 2, "#aaa9a2");
sphere(23, 21, 44, 1, "#c0bfb7");
sphere(27, 21, 44, 1, "#c0bfb7");
animate("smoke", { type: "bob", axis: "z", speed: 1, amplitude: 2 });