fogón

← Nature3D assetfogon/jacaranda

Jacarandá

by fogonCC09805 blocks
JacarandáDrag to turn it
// «Jacarandá» · gpt-6-sol (medium)
// A jacaranda tree in bloom: a dark brown trunk branching into a wide umbrella-shaped crown covered entirely in lilac and violet flowers in 3 shades, with a few violet petals scattered on the ground beneath.

// A jacaranda tree in bloom.
const bark = "#754428";
const barkDark = "#563320";
const barkLight = "#986139";
const violet = "#8f54c7";
const lilac = "#b97de8";
const paleLilac = "#d7a4f4";

// Flared trunk and chunky surface roots.
cylinder(24, 24, 0, 4, 5, bark);
cylinder(24, 24, 4, 3, 14, bark);
cylinder(24, 24, 17, 2, 7, bark);

for (const [x, y] of [[18, 24], [30, 24], [24, 18], [24, 30],
                      [20, 20], [28, 20], [20, 28], [28, 28]]) {
  line(24, 24, 4, x, y, 0, 1, barkDark);
  line(24, 24, 5, x, y, 1, 0, bark);
}

// Narrow bark grooves and warm highlights.
line(22, 21, 5, 22, 21, 16, 0, barkDark);
line(26, 22, 7, 26, 22, 15, 0, barkLight);
line(24, 21, 3, 24, 21, 11, 0, barkDark);
line(21, 24, 6, 21, 24, 13, 0, barkDark);
line(27, 24, 4, 27, 24, 12, 0, barkLight);

// Fallen petals stay on the ground while the crown sways.
for (let i = 0; i < 38; i++) {
  const a = rand() * Math.PI * 2;
  const r = 7 + rand() * 13;
  const x = Math.round(24 + Math.cos(a) * r);
  const y = Math.round(24 + Math.sin(a) * r);
  set(x, y, 0, [violet, lilac, paleLilac][i % 3]);
  if (i % 9 === 0) set(x + 1, y, 0, lilac);
}

part("crown", [24, 24, 23]);

// Branches radiate up into the broad, low umbrella.
for (let i = 0; i < 10; i++) {
  const a = i * Math.PI * 2 / 10;
  const reach = 11 + (i % 3);
  const x = 24 + Math.cos(a) * reach;
  const y = 24 + Math.sin(a) * reach;
  line(24, 24, 23, x, y, 32 + (i % 2), 1, barkDark);
  line(24, 24, 25, 24 + Math.cos(a) * 6,
       24 + Math.sin(a) * 6, 29, 1, bark);
}

// Rounded, overlapping masses make an umbrella silhouette.
ellipsoid(24, 24, 35, 17, 17, 5, violet);
ellipsoid(24, 24, 37, 13, 13, 5, violet);
for (let i = 0; i < 12; i++) {
  const a = i * Math.PI * 2 / 12;
  const r = 13.5 + (i % 3) * 0.6;
  ellipsoid(
    24 + Math.cos(a) * r,
    24 + Math.sin(a) * r,
    34 + (i % 3),
    5, 5, 4,
    violet
  );
}
ellipsoid(19, 23, 39, 6, 6, 4, violet);
ellipsoid(29, 26, 39, 6, 6, 4, violet);

// Three shades of blossoms: light on top, rich violet underneath.
const blossomChanges = [];
const raisedPetals = [];
forEach((x, y, z, color) => {
  if (color !== violet || z < 29) return;

  const skyward = !get(x, y, z + 1);
  const chance = rand();
  let shade;
  if (skyward) {
    shade = chance < 0.62 ? paleLilac : chance < 0.91 ? lilac : violet;
    if (rand() < 0.11 && z < 44) {
      raisedPetals.push([x, y, z + 1, rand() < 0.7 ? paleLilac : lilac]);
    }
  } else {
    shade = chance < 0.21 ? paleLilac : chance < 0.73 ? lilac : violet;
  }
  blossomChanges.push([x, y, z, shade]);
});
for (const p of blossomChanges) set(...p);
for (const p of raisedPetals) set(...p);

animate("crown", { type: "swing", axis: "y", speed: 1.2, amplitude: 0.08 });