fogón

← Asian3D assetfogon/bol-de-ramen

Bol de ramen

by fogonCC018477 blocks
Bol de ramenDrag to turn it
// «Bol de ramen» · gpt-6-sol (medium)
// A big bowl of ramen, chunky and appetizing: a deep red and black bowl with a white pattern on the rim, golden broth on top with wavy yellow noodles, a halved soft egg with orange yolk, two pink and white narutomaki slices, green onions, a square of nori sticking up and a pair of chopsticks resting on the rim.

const cx = 24, cy = 24;
const red = "#a92329", darkRed = "#761920";
const black = "#191b1b", gold = "#dbab49";
const white = "#f4e8d3";

function ring(radius, z, color, width = 0.6) {
  for (let a = 0; a < Math.PI * 2; a += 0.025) {
    for (let r = radius - width / 2; r <= radius + width / 2; r += 0.4) {
      set(cx + Math.cos(a) * r, cy + Math.sin(a) * r, z, color);
    }
  }
}

// Heavy foot and gently flaring, solid lacquered bowl.
for (let z = 0; z <= 22; z++) {
  const outer = z < 3 ? 11.5 : Math.min(20, 11.5 + (z - 2) * 0.46);
  for (let x = 3; x <= 45; x++) {
    for (let y = 3; y <= 45; y++) {
      const r = Math.hypot(x - cx, y - cy);
      if (r > outer) continue;

      let color;
      if (z <= 3) color = r > outer - 1.4 ? black : "#30302a";
      else if (z <= 17) {
        color = r > outer - 2.5
          ? (rand() < 0.11 ? darkRed : red)
          : "#6d3c22";
      } else if (z <= 20) {
        color = r > outer - 2.8
          ? (rand() < 0.16 ? "#34302b" : black)
          : "#b76d27";
      } else {
        if (r < 17.3) continue;
        color = z === 22 ? darkRed : red;
      }
      set(x, y, z, color);
    }
  }
}

ring(12.9, 4, gold);
ring(18.1, 16, "#d49b3b");
ring(19.5, 19, gold);
ring(19.6, 21, "#e4ae4b");
ring(19.4, 22, gold);

// White geometric motifs around the black upper band and across the lip.
for (let a = 0; a < Math.PI * 2; a += 0.012) {
  const motif = ((a / (Math.PI * 2) * 24) % 1 + 1) % 1;
  const d = Math.min(motif, 1 - motif);
  if (d < 0.13) {
    const r = 19.65;
    set(cx + Math.cos(a) * r, cy + Math.sin(a) * r, 20, white);
    if (d < 0.055) {
      set(cx + Math.cos(a) * r, cy + Math.sin(a) * r, 19, white);
      set(cx + Math.cos(a) * 18.5, cy + Math.sin(a) * 18.5, 22, white);
    }
  }
}

// Golden broth, with small pools of oil and warm surface variation.
for (let x = 7; x <= 41; x++) {
  for (let y = 7; y <= 41; y++) {
    const r = Math.hypot(x - cx, y - cy);
    if (r > 17.1) continue;
    const fleck = rand();
    set(x, y, 20,
      fleck < 0.12 ? "#edb84d" :
      fleck < 0.25 ? "#b9782b" : "#d99538");
    if (r < 16.4 && rand() < 0.27)
      set(x, y, 21, rand() < 0.5 ? "#eca94a" : "#c88330");
  }
}

// A nest of thick, undulating yellow noodles.
for (let strand = 0; strand < 12; strand++) {
  const baseY = 11.5 + strand * 2.25;
  let previous = null;
  for (let x = 10; x <= 38; x += 1.2) {
    const y = baseY + Math.sin(x * 0.57 + strand * 1.7) * 2.3;
    if (Math.hypot(x - cx, y - cy) > 16.2) {
      previous = null;
      continue;
    }
    const z = 21.5 + Math.sin(x * 0.39 + strand) * 0.65;
    if (previous)
      line(previous[0], previous[1], previous[2], x, y, z,
           0.7, strand % 3 === 0 ? "#ffe181" : "#f5c655");
    previous = [x, y, z];
  }
}

// Upright sheet of dark, lightly mottled nori at the back.
for (let x = 18; x <= 29; x++) {
  for (let z = 21; z <= 35; z++) {
    if (z === 35 && (x === 18 || x === 29)) continue;
    for (let y = 30; y <= 31; y++) {
      set(x, y, z, rand() < 0.19 ? "#29452e" : "#172b25");
    }
    if (rand() < 0.28) set(x, 29, z, "#3c6040");
  }
}
box(18, 30, 21, 29, 31, 21, "#344d30");

// Halved soft egg: plump white, shiny orange yolk facing upward.
ellipsoid(15, 17, 22, 5.1, 4.2, 2.6, "#ede6d2");
ellipsoid(15, 17, 24, 4.5, 3.5, 1.3, "#fff5dc");
ellipsoid(15, 16, 25, 2.7, 2.5, 1.2, "#ec8b24");
ellipsoid(14.7, 15.7, 26, 1.5, 1.3, 0.5, "#ffbd47");

// Two thick narutomaki slices, edged and spiraled in cherry pink.
function naruto(x, y, z) {
  cylinder(x, y, z, 3.7, 2, "#f5e9dd");
  for (let a = 0; a < Math.PI * 2; a += 0.07)
    set(x + 3.45 * Math.cos(a), y + 3.45 * Math.sin(a), z + 2, "#e88d9d");
  for (let t = 0; t < Math.PI * 3.3; t += 0.12) {
    const r = 0.35 + t * 0.18;
    set(x + r * Math.cos(t), y + r * Math.sin(t), z + 2, "#e77c97");
  }
}
naruto(31, 16, 22);
naruto(36, 24, 21);

// Chopped jade-green scallions, scattered in small clusters.
const scallions = [
  [12, 26], [15, 29], [18, 27], [12, 32], [16, 34],
  [26, 12], [24, 16], [27, 23], [32, 28], [36, 29],
  [22, 36], [10, 22], [28, 35]
];
for (const [x, y] of scallions) {
  cylinder(x, y, 21, 1.5, 2, "#4e933e");
  set(x, y, 23, "#b8ca70");
  if (rand() < 0.65) set(x + 1, y, 23, "#75af55");
}

// Parallel lacquered chopsticks resting diagonally across opposite rim edges.
line(7, 11, 24, 40, 35, 24, 0, "#713726");
line(9, 9, 25, 42, 33, 25, 0, "#8b4930");
line(7, 11, 24, 14, 16, 24, 0, "#bc7440");
line(9, 9, 25, 16, 14, 25, 0, "#cf8750");
for (const [x, y, z] of [[11, 14, 24], [13, 12, 25]]) {
  set(x, y, z, gold);
  set(x + 1, y + 1, z, gold);
}