fogón

← NaturalezaObjeto 3Dfogon/arbol-cono

Ciprés

de fogonCC05209 bloques
CiprésArrastrá para girarlo
// «Ciprés» · gpt-6-sol (medium)
// A tall narrow cypress tree: a dense dark green flame-shaped column, pointed at the top and slightly bulging in the middle, with only a tiny bit of brown trunk at the base.

// A slim, flame-shaped cypress with a small visible trunk.
const cx = 24, cy = 24;

const bark = ["#754624", "#8b572d", "#a66a37"];
for (let z = 0; z <= 5; z++) {
  for (let x = 22; x <= 26; x++) {
    for (let y = 22; y <= 26; y++) {
      if ((x - cx) ** 2 + (y - cy) ** 2 <= 3.2) {
        const groove = (x === 22 || (y === 25 && x === 24));
        set(x, y, z, groove ? bark[0] : (z > 2 ? bark[1] : bark[2]));
      }
    }
  }
}

const profile = [
  [3, 2.7], [5, 4.1], [9, 5.4], [14, 6.6],
  [20, 7.7], [25, 8.2], [29, 7.8], [34, 6.5],
  [38, 5.0], [41, 3.4], [44, 0.8]
];

function radiusAt(z) {
  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;
}

const greens = ["#17462e", "#205a35", "#286e3c", "#348549", "#459b51"];

for (let z = 3; z <= 44; z++) {
  const r = radiusAt(z);
  const midX = cx + 0.4 * Math.sin(z * 0.20);
  const midY = cy + 0.3 * Math.sin(z * 0.16 + 1);

  for (let x = 14; x <= 34; x++) {
    for (let y = 14; y <= 34; y++) {
      const dx = x - midX, dy = y - midY;
      const angle = Math.atan2(dy, dx);
      const scallop = 0.28 * Math.sin(angle * 7 + z * 0.35)
                    + 0.22 * Math.sin(angle * 11 - z * 0.24);
      const edge = r + scallop;
      const distance = Math.hypot(dx, dy);
      if (distance > edge) continue;

      // Broad, chunky patches of foliage rather than fine pixel noise.
      const patch = Math.sin(Math.floor(x / 3) * 2.3 +
                             Math.floor(y / 3) * 3.7 +
                             Math.floor(z / 4) * 1.9);
      let shade = 1;
      if (y < cy - 1) shade++;
      if (x < cx - 1) shade++;
      if (z > 27) shade++;
      if (z < 10) shade--;
      if (patch > 0.48) shade++;
      if (patch < -0.62) shade--;
      if (distance < edge - 2) shade = Math.min(shade, 2);
      shade = Math.max(0, Math.min(4, shade));
      set(x, y, z, greens[shade]);
    }
  }
}

// Soft overlapping leafy tips give the sides a rounded storybook texture.
for (let z = 7; z <= 39; z += 4) {
  const r = radiusAt(z);
  for (let j = 0; j < 5; j++) {
    const a = j * Math.PI * 2 / 5 + z * 0.31;
    const distance = r - 1.35;
    const x = cx + Math.cos(a) * distance;
    const y = cy + Math.sin(a) * distance;
    const lit = y < cy;
    ellipsoid(x, y, z + (j % 2), 1.45, 1.45, 2,
              lit ? (z > 26 ? "#459b51" : "#348549") : "#286e3c");
  }
}

// Restore the crisp, narrow point above the last rounded foliage tufts.
set(24, 24, 44, "#459b51");