fogón

← BásicoObjeto 3Dfogon/cerezas

Cerezas

de fogonCC011260 bloques
CerezasArrastrá para girarlo
// «Cerezas» · gpt-6-sol (medium)
// Cherries («Cerezas»).

// Two cherries, one in front of the other.
function cherry(cx, cy, cz, rx, ry, rz, seed) {
  for (let x = Math.floor(cx - rx); x <= Math.ceil(cx + rx); x++)
    for (let y = Math.floor(cy - ry); y <= Math.ceil(cy + ry); y++)
      for (let z = Math.max(0, Math.floor(cz - rz)); z <= Math.ceil(cz + rz); z++) {
        const dx = (x - cx) / rx;
        const dy = (y - cy) / ry;
        const dz = (z - cz) / rz;

        // Slightly flattened top and a subtly uneven, pixelated outline.
        const ripple = 0.035 * Math.sin(x * 1.7 + seed) * Math.cos(y * 1.3);
        if (dx * dx + dy * dy + dz * dz > 1 + ripple) continue;

        const n = rand();
        let color;
        if (z < cz - 6) color = n < 0.18 ? "#8d1429" : n < 0.55 ? "#a51730" : "#b51b32";
        else if (z < cz + 2) color = n < 0.15 ? "#aa172d" : n < 0.68 ? "#c51d36" : "#d82a40";
        else color = n < 0.2 ? "#b91b31" : n < 0.75 ? "#d6263d" : "#e4384a";

        // Narrow dark-red facets on the sides of the fruit.
        if (Math.abs(dx) > 0.68 && z < cz + 3 && (x + 2 * y) % 5 === 0)
          color = "#a8172e";
        set(x, y, z, color);
      }

  // Small dimple beneath the stem.
  for (let x = cx - 2; x <= cx + 2; x++)
    for (let y = cy - 2; y <= cy + 2; y++)
      if (Math.abs(x - cx) + Math.abs(y - cy) < 4)
        set(x, y, Math.round(cz + rz - 1), "#a91b30");
}

// The rear cherry is higher and partly hidden by the front one.
cherry(31, 29, 18.5, 10.5, 9.7, 10.8, 2);
cherry(17, 17, 12, 11.5, 10.5, 12, 5);

// Little patches of reflected light on the forward-facing skins.
function glint(cx, cy, cz, rx, ry, rz, pixels) {
  for (const [x, z, color] of pixels) {
    const dx = (x - cx) / rx, dz = (z - cz) / rz;
    const span = 1 - dx * dx - dz * dz;
    if (span <= 0) continue;
    const y = Math.ceil(cy - ry * Math.sqrt(span));
    set(x, y, z, color);
  }
}
glint(17, 17, 12, 11.5, 10.5, 12, [
  [21, 20, "#ef7773"], [22, 21, "#ffd5bd"], [23, 21, "#fff0db"],
  [24, 20, "#ffe0c8"], [22, 19, "#fff1d9"], [23, 19, "#f9c5b5"],
  [24, 18, "#f5a099"], [21, 18, "#ee7778"], [25, 17, "#e77a79"]
]);
glint(31, 29, 18.5, 10.5, 9.7, 10.8, [
  [34, 25, "#f28d89"], [35, 26, "#ffe4cc"], [36, 25, "#fff0da"],
  [37, 24, "#f7ccb8"], [35, 24, "#ffe8cf"], [36, 23, "#f5aaa1"],
  [34, 23, "#ed7777"]
]);

// Paired, angular olive stems meet above the cherries.
line(17, 17, 23, 17, 17, 29, 1, "#695e27");
line(17, 17, 29, 20, 19, 34, 1, "#75682b");
line(20, 19, 34, 23, 23, 38, 1, "#807631");
line(23, 23, 38, 26, 25, 39, 1, "#665b28");

line(31, 29, 28, 30, 29, 34, 1, "#635c2b");
line(30, 29, 34, 27, 27, 38, 1, "#70672a");
line(27, 27, 38, 25, 25, 39, 1, "#796d2c");

// Warm sunlit edges make the stems legible against the fruit.
line(16, 16, 25, 16, 16, 29, 0, "#a39943");
line(19, 18, 31, 21, 20, 35, 0, "#ad9d49");
line(29, 28, 32, 28, 27, 35, 0, "#a7973c");

// A single broad leaf grows to the right of their joined stems.
for (let x = 26; x <= 40; x++)
  for (let y = 22; y <= 32; y++)
    for (let z = 36; z <= 43; z++) {
      const u = (x - 33) / 7.5;
      const v = (y - (26 + (x - 26) * 0.18)) / 4.4;
      const w = (z - (39.5 - (x - 33) * 0.12)) / 3.5;
      if (u * u + v * v + w * w > 1) continue;

      let color = z >= 41 ? "#79a743" : z <= 38 ? "#477a36" : "#5e973c";
      if (rand() < 0.19) color = z >= 40 ? "#94b657" : "#3d7934";
      set(x, y, z, color);
    }

// Leaf midrib and a few chunky veins.
line(26, 25, 40, 38, 28, 39, 0, "#a6b95c");
line(31, 26, 40, 33, 23, 41, 0, "#92b558");
line(35, 27, 39, 37, 31, 40, 0, "#83aa49");
line(28, 25, 40, 31, 23, 41, 0, "#b2bd65");