fogón

← Basics3D assetfogon/maceta

Maceta

by fogonCC017834 blocks
MacetaDrag to turn it
// «Maceta» · gpt-6-sol (medium)
// Flowerpot («Maceta»).

const terracotta = ["#a95836", "#bd6a40", "#ce7848", "#dc8b56", "#e59b63"];
const darkClay = "#88482f";

function potLayer(z, radius, inner = -1) {
  for (let x = 5; x <= 43; x++) {
    for (let y = 5; y <= 43; y++) {
      const dx = x - 24, dy = y - 24;
      const a = Math.atan2(dy, dx);
      const d = Math.hypot(dx, dy);
      const flute = z < 20 ? 0.38 * Math.cos(a * 24) : 0.15 * Math.cos(a * 24);
      if (d > radius + flute || d < inner) continue;

      const edge = d > radius - 2;
      const light = (24 - x) * 0.055 + (24 - y) * 0.035;
      let shade = Math.max(0, Math.min(4, Math.round(2 + light)));
      if (edge && Math.cos(a * 24) < -0.25) shade--;
      if (edge && rand() < 0.09) shade += rand() < 0.5 ? -1 : 1;
      shade = Math.max(0, Math.min(4, shade));
      set(x, y, z, terracotta[shade]);
    }
  }
}

// Broad foot, tapered fluted body, and thick rolled rim.
for (let z = 0; z <= 3; z++) potLayer(z, z === 0 ? 14.5 : 15.6);
potLayer(4, 14.2);
for (let z = 5; z <= 17; z++) potLayer(z, 12.3 + (z - 5) * 0.14);
potLayer(18, 14.5);
for (let z = 19; z <= 22; z++) potLayer(z, 16.1 + (z >= 21 ? 0.5 : 0));
for (let z = 23; z <= 25; z++) potLayer(z, z === 25 ? 16.6 : 17.1, 13.2);

// Dark grooves under the rim and along the foot.
for (let i = 0; i < 36; i++) {
  const a = i * Math.PI * 2 / 36;
  for (const z of [2, 19, 21]) {
    const r = z === 2 ? 15.5 : z === 19 ? 16.1 : 16.6;
    set(24 + Math.cos(a) * r, 24 + Math.sin(a) * r, z,
        i % 3 === 0 ? "#f0aa70" : darkClay);
  }
}
for (let i = 0; i < 24; i++) {
  const a = i * Math.PI * 2 / 24;
  for (let z = 5; z <= 17; z++) {
    const r = 12.3 + (z - 5) * 0.14;
    const c = i % 3 === 0 ? "#e3945c" : i % 3 === 1 ? "#a85b38" : "#c57447";
    set(24 + Math.cos(a) * r, 24 + Math.sin(a) * r, z, c);
  }
}

// The soil sits just below the top edge.
for (let x = 11; x <= 37; x++) for (let y = 11; y <= 37; y++) {
  const d = Math.hypot(x - 24, y - 24);
  if (d < 12.9) {
    set(x, y, 23, rand() < 0.22 ? "#624530" : "#483b2d");
    if (rand() < 0.13) set(x, y, 24, rand() < 0.5 ? "#775039" : "#342f26");
  }
}

// Green stems, partly hidden by foliage.
line(23, 24, 23, 19, 29, 39, 1, "#205b30");
line(25, 24, 23, 31, 26, 36, 1, "#286935");
line(21, 21, 23, 14, 17, 32, 1, "#255f31");
line(19, 28, 27, 18, 29, 37, 0, "#479546");
line(30, 26, 28, 31, 26, 35, 0, "#52a34b");

// Pointed, chunky leaves with a raised central vein.
function leaf(x0, y0, z0, x1, y1, z1, width) {
  const dx = x1 - x0, dy = y1 - y0;
  const length = Math.hypot(dx, dy);
  const nx = -dy / length, ny = dx / length;
  const steps = Math.ceil(length * 2);
  for (let i = 0; i <= steps; i++) {
    const t = i / steps;
    const spread = width * Math.sin(Math.PI * t) * (0.8 + 0.2 * t);
    const x = x0 + dx * t, y = y0 + dy * t;
    const z = Math.round(z0 + (z1 - z0) * t + Math.sin(Math.PI * t));
    for (let s = -Math.ceil(spread); s <= Math.ceil(spread); s++) {
      if (Math.abs(s) > spread + 0.25) continue;
      const bx = Math.round(x + nx * s), by = Math.round(y + ny * s);
      set(bx, by, z - 1, "#174f2b");
      set(bx, by, z, Math.abs(s) > spread - 0.8 ? "#216431" : "#2e813b");
      if (Math.abs(s) < 0.65) set(bx, by, z + 1, "#58aa4e");
      else if (s < 0 && rand() < 0.55) set(bx, by, z + 1, "#399349");
    }
  }
}
leaf(23, 24, 26, 37, 19, 29, 2.7);
leaf(23, 25, 27, 34, 30, 31, 2.3);
leaf(22, 23, 27, 12, 22, 29, 2.4);
leaf(23, 23, 26, 17, 14, 29, 2.3);
leaf(21, 27, 30, 14, 31, 32, 1.9);
leaf(27, 25, 28, 32, 16, 31, 2.0);
leaf(22, 20, 25, 28, 13, 27, 1.8);

// Flowers face forward (-y). Layered petals leave their centers prominent.
function flower(cx, cy, cz, outer, shadow, highlight, centerDark, centerLight, size) {
  ellipsoid(cx, cy + 1, cz, size * 0.82, 1.6, size * 0.85, shadow);
  const petals = 8;
  for (let i = 0; i < petals; i++) {
    const a = i * Math.PI * 2 / petals + Math.PI / 8;
    const px = cx + Math.cos(a) * size * 0.64;
    const pz = cz + Math.sin(a) * size * 0.68;
    ellipsoid(px, cy, pz, 1.9, 1.4, 2.1, outer);
    ellipsoid(px - 0.35, cy - 0.8, pz + 0.5, 1.05, 0.8, 1.15,
              i % 3 === 0 ? highlight : outer);
    if (i % 2 === 0)
      set(px + Math.cos(a) * 1.6, cy, pz + Math.sin(a) * 1.5, highlight);
  }
  ellipsoid(cx, cy - 1.6, cz, size * 0.45, 1.3, size * 0.46, centerDark);
  ellipsoid(cx - 0.3, cy - 2.5, cz + 0.1, size * 0.32, 0.8, size * 0.33, centerLight);
}

// Tall golden bloom, smaller rose bloom, and the low violet bloom.
flower(19, 28, 39, "#d6a52f", "#9a7525", "#f3c94c",
       "#674225", "#a57134", 5.0);
flower(31, 24, 36, "#cf777c", "#a85661", "#eda0a0",
       "#a86648", "#f4d19a", 4.4);
flower(14, 16, 32, "#926ab0", "#624b82", "#b18bcc",
       "#a47639", "#f1cc78", 4.5);