fogón

← BásicoObjeto 3Dfogon/anana-maduro

Ananá maduro

de fogonCC011643 bloques
Ananá maduroArrastrá para girarlo
// «Ananá maduro» · gpt-6-sol (medium)
// Pineapple («Ananá maduro»).

// Pineapple — Ananá maduro
const cx = 24, cy = 24;

function radiusAt(z) {
  const profile = [
    [0, 5.5], [2, 8], [5, 10], [9, 11.5],
    [15, 12], [21, 11.5], [25, 10], [28, 7.5], [29, 4.5]
  ];
  for (let i = 1; i < profile.length; i++) {
    if (z <= profile[i][0]) {
      const [z0, r0] = profile[i - 1];
      const [z1, r1] = profile[i];
      return r0 + (r1 - r0) * (z - z0) / (z1 - z0);
    }
  }
  return 0;
}

function edgeDistance(v, period) {
  const p = ((v % period) + period) % period;
  return Math.min(p, period - p);
}

// Solid, softly rounded golden fruit.
for (let z = 0; z <= 29; z++) {
  const r = radiusAt(z);
  for (let x = 11; x <= 37; x++) {
    for (let y = 11; y <= 37; y++) {
      const dx = x - cx, dy = y - cy;
      const rr = Math.sqrt(dx * dx + (dy / 0.94) ** 2);
      if (rr > r) continue;

      const surface = rr > r - 1.35 || z === 29;
      let color = z < 6 ? "#b77b22" : z > 23 ? "#d99b29" : "#cb8d24";

      if (surface) {
        const angle = Math.atan2(dy / 0.94, dx);
        const arc = angle * 11.5;
        const a = edgeDistance(arc + z * 1.06, 6);
        const b = edgeDistance(arc - z * 1.06, 6);
        const light = dx < 0 && dy < 2;

        // Crossing diagonal seams outline the pineapple's diamond-shaped eyes.
        if (a < 0.58 && b < 0.58) color = "#86551c";
        else if (a < 0.72 || b < 0.72)
          color = light ? "#aa711e" : "#98621c";
        else if (a < 1.35 || b < 1.35)
          color = light ? "#f0b83c" : "#df9d29";
        else
          color = light ? "#e9ae35" : "#d09225";

        if (rand() < 0.14)
          color = light ? "#f4c54b" : "#b97820";
        if (z < 5 && rand() < 0.45) color = "#a96d20";
      }
      set(x, y, z, color);
    }
  }
}

// Small, raised golden scales catch the light along the fruit's front.
for (let z = 3; z <= 27; z++) {
  const r = radiusAt(z);
  for (let x = 13; x <= 35; x++) {
    const dx = x - cx;
    const front = cy - Math.round(0.94 * Math.sqrt(Math.max(0, r * r - dx * dx)));
    if (front >= cy || !get(x, front, z)) continue;
    const arc = Math.atan2((front - cy) / 0.94, dx) * 11.5;
    const a = edgeDistance(arc + z * 1.06, 6);
    const b = edgeDistance(arc - z * 1.06, 6);
    if (a > 0.9 && a < 1.7 && b > 0.9 && b < 1.8 && rand() < 0.58)
      set(x, front - 1, z, rand() < 0.35 ? "#f5c54a" : "#e5aa31");
  }
}

// Dense dark-green socket at the base of the crown.
ellipsoid(cx, cy, 29, 5, 5, 3, "#315e26");
ellipsoid(cx, cy, 31, 3, 3, 2, "#427a2d");

function leaf(angle, startR, length, baseZ, lift, width) {
  const dx = Math.cos(angle), dy = Math.sin(angle);
  const px = -dy, py = dx;
  const steps = Math.ceil(length * 1.7);

  for (let i = 0; i <= steps; i++) {
    const t = i / steps;
    const r = startR + length * t;
    const x = cx + dx * r, y = cy + dy * r;
    const z = baseZ + lift * Math.sin(Math.PI * t * 0.8) - 1.2 * t;
    const w = Math.max(0, Math.round(width * (1 - t) - 0.15));

    for (let side = -w; side <= w; side++) {
      const bx = Math.round(x + px * side);
      const by = Math.round(y + py * side);
      const bz = Math.round(z);
      set(bx, by, bz, side === 0 ? "#346c27" : "#285821");
      if (t < 0.9) {
        set(bx, by, bz + 1,
          side < 0 ? "#66a63b" : side === 0 ? "#4d8d32" : "#39732a");
      }
    }
  }
}

// Long, narrow leaves spread outward in staggered, spiky whorls.
for (let ring = 0; ring < 3; ring++) {
  const count = ring === 0 ? 15 : ring === 1 ? 13 : 11;
  for (let i = 0; i < count; i++) {
    const angle = i * Math.PI * 2 / count + ring * 0.43;
    const length = (ring === 0 ? 13 : ring === 1 ? 16 : 11) + rand() * 2;
    leaf(angle, ring === 2 ? 1 : 2, length,
      ring === 0 ? 30 : ring === 1 ? 32 : 34,
      ring === 1 ? 3.5 : 2.5, ring === 1 ? 1.5 : 1);
  }
}

// Upright, slightly splayed pointed leaves complete the tall crown.
for (let i = 0; i < 17; i++) {
  const angle = i * Math.PI * 2 / 17 + 0.2;
  const height = 7 + rand() * 7;
  const reach = 2.5 + rand() * 5;
  const dx = Math.cos(angle), dy = Math.sin(angle);
  const px = -dy, py = dx;

  for (let j = 0; j <= Math.ceil(height * 1.5); j++) {
    const t = j / Math.ceil(height * 1.5);
    const r = 0.5 + reach * t * t;
    const x = Math.round(cx + dx * r);
    const y = Math.round(cy + dy * r);
    const z = Math.round(32 + height * t);
    const broad = t < 0.53 && i % 3 !== 0;

    set(x, y, z, "#326b29");
    if (broad) set(Math.round(x + px), Math.round(y + py), z, "#4c8d34");
    if (t > 0.18 && t < 0.9) set(x, y, z + 1, "#65a942");
  }
}