fogón

← Piratas y marObjeto 3Dfogon/botella-con-mensaje

Botella con mensaje

de fogonCC08739 bloques
Botella con mensajeArrastrá para girarlo
// «Botella con mensaje» · gpt-6-sol (medium)
// A big green glass bottle lying on its side half in the sand, a cork in the neck and a rolled beige paper scroll tied with a red string visible inside.

// A message in a bottle, half-buried on a sunny pirate beach.
const glassDark = "#126453";
const glassMid = "#188c70";
const glassLight = "#30b793";
const glassShine = "#84e5bc";
const sand = ["#dfae62", "#edc47d", "#f5d594"];
const sandShadow = "#c99551";
const paper = "#f3dfad";
const paperEdge = "#cda773";
const red = "#c73836";

function radiusAt(x) {
  if (x < 10) return 5.8 + (x - 7) * 1.15; // rounded base
  if (x <= 27) return 9.3;
  if (x <= 33) return 9.3 - (x - 27) * 0.85; // shoulder
  if (x <= 40) return 4.2;
  return 0;
}

// Low, irregular oval patch of beach.
for (let x = 4; x <= 45; x++)
for (let y = 8; y <= 40; y++) {
  const d = ((x - 24) / 21) ** 2 + ((y - 24) / 16) ** 2;
  if (d > 1 || (d > 0.88 && rand() < 0.35)) continue;
  let h = 1;
  if (y < 18) h += Math.max(0, Math.floor((18 - y) / 3));
  if (y > 31) h += Math.max(0, Math.floor((y - 31) / 5));
  if (rand() < 0.15) h++;
  for (let z = 0; z <= h; z++)
    set(x, y, z, z === h ? sand[Math.floor(rand() * 3)] : sandShadow);
}

// Bottle body: solid colored glass, with its broad front face opened up
// to show the letter through the green glass.
for (let x = 7; x <= 40; x++) {
  const r = radiusAt(x);
  for (let y = 13; y <= 35; y++)
  for (let z = 1; z <= 21; z++) {
    const dy = (y - 24) / r, dz = (z - 11) / (r * 0.94);
    const distance = dy * dy + dz * dz;
    if (distance > 1) continue;

    // A dark green interior behind the scroll.
    let color = glassDark;
    if (z >= 13) color = glassMid;
    if (z >= 17 && y <= 26) color = glassLight;
    if (distance > 0.78 && y < 24) color = glassMid;
    if (distance > 0.88 && z >= 15 && y < 23) color = glassShine;
    if (rand() < 0.035) color = z > 11 ? glassLight : glassDark;
    set(x, y, z, color);
  }
}

// Clear viewing area in the near side. Retain a chunky glass border.
for (let x = 13; x <= 30; x++)
for (let y = 13; y <= 20; y++)
for (let z = 7; z <= 15; z++) {
  if (get(x, y, z)) set(x, y, z, null);
}

// Dark inner edge makes the glass wall read as thick.
for (let x = 13; x <= 30; x++) {
  for (const z of [6, 16])
    for (let y = 15; y <= 19; y++)
      if (get(x, y, z)) set(x, y, z, glassDark);
}

// Rolled parchment inside, running along the bottle.
for (let x = 15; x <= 29; x++)
for (let y = 16; y <= 23; y++)
for (let z = 7; z <= 15; z++) {
  const d = ((y - 19.7) / 3.1) ** 2 + ((z - 11) / 3.1) ** 2;
  if (d <= 1) {
    let c = z >= 12 ? "#fff0c9" : paper;
    if (d > 0.7 || z <= 8) c = paperEdge;
    if (rand() < 0.035) c = "#dfc390";
    set(x, y, z, c);
  }
}

// Pale curled end of the rolled sheet.
for (let y = 17; y <= 23; y++)
for (let z = 8; z <= 14; z++) {
  const d = ((y - 19.7) / 3.1) ** 2 + ((z - 11) / 3.1) ** 2;
  if (d <= 1) set(30, y, z, d > 0.58 ? paperEdge : "#fff0c9");
}
set(30, 17, 11, paperEdge);
set(30, 18, 12, paperEdge);
set(30, 19, 12, paperEdge);
set(30, 20, 11, paperEdge);
set(30, 19, 10, paperEdge);

// Red string bound around the middle, including its front-facing knot.
for (let x = 22; x <= 23; x++)
for (let y = 16; y <= 23; y++)
for (let z = 7; z <= 15; z++) {
  const d = ((y - 19.7) / 3.2) ** 2 + ((z - 11) / 3.2) ** 2;
  if (d > 0.66 && d < 1.13) set(x, y, z, x === 22 ? red : "#ed5a43");
}
box(21, 15, 11, 23, 16, 12, "#a82730");
set(22, 14, 10, red);
set(21, 15, 9, "#ed5a43");
set(23, 15, 9, "#ed5a43");

// Narrow neck, raised lip, and the chunky cork in its mouth.
for (let x = 39; x <= 41; x++)
for (let y = 19; y <= 29; y++)
for (let z = 6; z <= 16; z++) {
  const d = ((y - 24) / 5.2) ** 2 + ((z - 11) / 5.2) ** 2;
  if (d <= 1 && d >= 0.49)
    set(x, y, z, z >= 13 ? glassLight : glassDark);
}
for (let x = 41; x <= 45; x++)
for (let y = 20; y <= 28; y++)
for (let z = 7; z <= 15; z++) {
  const d = ((y - 24) / 3.6) ** 2 + ((z - 11) / 3.6) ** 2;
  if (d <= 1) {
    let c = z > 11 ? "#dfaa6b" : "#b97946";
    if (d > 0.72 || rand() < 0.1) c = "#995d39";
    set(x, y, z, c);
  }
}
box(44, 22, 10, 45, 26, 12, "#dca16a");

// Sparkling glass streaks across the rounded upper surface.
for (let x = 12; x <= 26; x++)
  if (x % 5 !== 0) set(x, 19, 19, glassShine);
for (let x = 10; x <= 16; x++) set(x, 16, 15, glassLight);
for (let x = 32; x <= 37; x++) set(x, 21, 15, glassShine);
set(10, 17, 18, "#d0ffe0");
set(11, 17, 18, "#d0ffe0");
set(10, 17, 19, "#d0ffe0");

// Fresh sand bank against the lower front of the bottle.
for (let x = 8; x <= 37; x++)
for (let y = 12; y <= 18; y++) {
  let h = Math.floor(2 + (18 - y) * 0.45 + Math.sin(x * 0.42) * 0.8);
  if (rand() < 0.12) h++;
  for (let z = 1; z <= h; z++) {
    if (z <= 3 || y <= 16 || (x < 13 && z <= 5))
      set(x, y, z, z === h ? sand[Math.floor(rand() * 3)] : "#deb06b");
  }
}

// A couple of little gold glints washed up nearby.
for (const [x, y] of [[33, 12], [35, 13]]) {
  box(x, y, 3, x + 2, y + 1, 3, "#b47b20");
  box(x, y, 4, x + 1, y + 1, 4, "#ffd456");
  set(x, y, 5, "#ffe98b");
}