fogón

← Nature3D assetfogon/matas-de-pasto

Mata de pasto

by fogonCC02217 blocks
Mata de pastoDrag to turn it
// «Mata de pasto» · gpt-6-sol (medium)
// A clump of tall grass blades in 3 shades of green, spiky and wild, growing from one spot.

// A single swaying clump of chunky, tapered grass blades.
part("grass", [24, 24, 0]);

const greens = ["#238d3d", "#32ad47", "#54ce53"];
const sunlit = "#77de66";

// Each blade grows from the same small patch, then bends outward.
const blades = [
  // angle, height, outward reach, width, shade
  [  0, 29, 17, 2.4, 1], [ 22, 34, 15, 2.0, 2],
  [ 43, 26, 18, 2.5, 1], [ 63, 32, 16, 2.1, 0],
  [ 83, 25, 18, 2.6, 2], [105, 35, 14, 2.0, 1],
  [125, 28, 17, 2.4, 2], [146, 33, 16, 2.1, 0],
  [167, 27, 18, 2.5, 1], [188, 31, 17, 2.2, 2],
  [210, 25, 18, 2.5, 0], [231, 34, 15, 2.0, 1],
  [252, 28, 18, 2.3, 2], [273, 32, 17, 2.2, 1],
  [295, 26, 18, 2.4, 0], [316, 35, 15, 2.0, 2],
  [339, 28, 18, 2.5, 1],
  // Taller, more upright blades give the center its spiky crown.
  [ 12, 39,  8, 2.0, 2], [ 74, 37,  9, 1.8, 1],
  [137, 40,  7, 1.9, 2], [196, 37, 10, 2.0, 1],
  [258, 39,  8, 1.8, 0], [321, 38,  9, 1.9, 2]
];

// Dense, irregular little base rather than a separate pot or soil mound.
ellipsoid(24, 24, 1, 5, 5, 2, greens[0]);
ellipsoid(24, 24, 2, 4, 4, 2, greens[1]);

for (const [degrees, height, reach, width, shade] of blades) {
  const a = degrees * Math.PI / 180;
  const dx = Math.cos(a), dy = Math.sin(a);
  const sideX = -dy, sideY = dx;
  const offset = (rand() - 0.5) * 2;

  for (let z = 1; z <= height; z++) {
    const t = z / height;
    const bend = reach * Math.pow(t, 1.65);
    const sideways = offset * (1 - t) + Math.sin(t * Math.PI) * 0.8;
    const cx = 24 + dx * bend + sideX * sideways;
    const cy = 24 + dy * bend + sideY * sideways;

    // Broad lower leaves, narrowing steadily into a sharp one-block tip.
    const halfWidth = Math.max(0.4, width * (1 - Math.pow(t, 1.5)));
    const halfThickness = t > 0.84 ? 0.45 : 0.85;

    for (let u = -Math.ceil(halfWidth); u <= Math.ceil(halfWidth); u++) {
      for (let v = -1; v <= 1; v++) {
        if ((u * u) / (halfWidth * halfWidth + 0.15) +
            (v * v) / (halfThickness * halfThickness + 0.15) > 1.2) continue;

        let color = greens[shade];
        if (v === -1 || (u > 0 && t > 0.35)) color = greens[2];
        if (t > 0.72 && v <= 0 && (z + u) % 3 !== 0) color = sunlit;
        if (t < 0.2 && v > 0) color = greens[0];

        set(
          Math.round(cx + sideX * u + dx * v),
          Math.round(cy + sideY * u + dy * v),
          z,
          color
        );
      }
    }
  }
}

animate("grass", { type: "swing", axis: "y", speed: 1.6, amplitude: 0.12 });