fogón

← Animals3D assetfogon/mariquita

Mariquita

by fogonCC021435 blocks
MariquitaDrag to turn it
// «Mariquita» · gpt-6-sol (medium)
// A cartoon ladybug, horizontal along y, head at the front (-y): a domed glossy red shell with big black spots and a black line down the middle, a black head with two white eye dots and antennae, and six small black legs.

// Six short legs and rounded feet.
for (const y of [17, 28, 39]) {
  for (const side of [-1, 1]) {
    const x = 24 + side * 13;
    line(x, y, 10, x + side * 7, y - 1, 3, 2, "#202126");
    ellipsoid(x + side * 7, y - 1, 2, 3, 3, 2, "#151619");
  }
}

// Dark, plump body beneath the wing covers.
ellipsoid(24, 27, 13, 16, 18, 10, "#202126");
ellipsoid(24, 26, 11, 14, 16, 7, "#2b2c31");

// Big round head at the front.
ellipsoid(24, 10, 16, 10, 8, 9, "#191a1e");
ellipsoid(24, 7, 19, 8, 5, 5, "#25262b");
for (const x of [19, 29]) {
  ellipsoid(x, 3, 18, 2, 2, 2, "#ffffff");
  set(x - 1, 1, 19, "#ffffff");
}

// Cheerful little antennae.
for (const side of [-1, 1]) {
  line(24 + side * 6, 7, 23, 24 + side * 8, 4, 31, 1, "#202126");
  sphere(24 + side * 8, 4, 31, 2, "#25262b");
}

function shellTop(x, y) {
  const d = ((x - 24) / 18) ** 2 + ((y - 27) / 18) ** 2;
  return d <= 1 ? Math.floor(14 + 17 * Math.sqrt(1 - d)) : -1;
}

// A raised black center seam stays visible when the wings open.
for (let y = 10; y <= 44; y++) {
  for (let x = 23; x <= 24; x++) {
    const top = shellTop(x, y);
    if (top >= 15) box(x, y, 15, x, y, top, "#17181b");
  }
}

const spots = [
  [15, 19, 3.5], [13, 31, 3.7], [18, 39, 2.9],
  [33, 19, 3.5], [35, 31, 3.7], [30, 39, 2.9]
];

// Each red half is its own wing cover, hinged near the head.
for (const side of [-1, 1]) {
  const name = side < 0 ? "left shell" : "right shell";
  part(name, [24 + side, 12, 17]);

  for (let x = side < 0 ? 6 : 25; x <= (side < 0 ? 22 : 42); x++) {
    for (let y = 9; y <= 45; y++) {
      const top = shellTop(x, y);
      if (top < 15) continue;

      const d = ((x - 24) / 18) ** 2 + ((y - 27) / 18) ** 2;
      for (let z = 14; z <= top; z++) {
        let color;
        if (z < 17 || d > 0.88) color = "#aa2027";
        else if (z >= 25 && rand() > 0.18) color = "#f44442";
        else color = rand() < 0.12 ? "#d52c32" : "#e63738";

        // Bold spots follow the curved top rather than sinking into it.
        if (z >= top - 2) {
          for (const [sx, sy, r] of spots) {
            const distance = ((x - sx) / r) ** 2 + ((y - sy) / r) ** 2;
            if (distance < 1) {
              color = distance > 0.78 ? "#303034" : "#17181b";
              break;
            }
          }
        }
        set(x, y, z, color);
      }
    }
  }

  // Small glossy glints on the front of each shell.
  for (let y = 14; y <= 18; y++) {
    for (let x = side < 0 ? 17 : 28; x <= (side < 0 ? 20 : 31); x++) {
      const top = shellTop(x, y);
      if (top > 17 && (x + y) % 5 !== 0) set(x, y, top, "#ff7770");
    }
  }

  animate(name, {
    type: "swing",
    axis: "y",
    speed: side < 0 ? -2 : 2,
    amplitude: 0.2
  });
}

part("body", [24, 24, 14]);