fogón

← Animals3D assetfogon/tortuga

Tortuga

by fogonCC021055 blocks
TortugaDrag to turn it
// «Tortuga» · gpt-6-sol (medium)
// A cartoon land tortoise, horizontal along y, head at the front (-y): a high domed shell in dark green with lighter green hexagon plates outlined in brown, a wide flat shell rim, a wrinkly olive head with black dot eyes and a little smile poking out the front, four stubby olive legs at the corners and a tiny tail.

// Chunky body beneath the shell.
ellipsoid(24, 25, 12, 13, 15, 8, "#6f8b3e");
ellipsoid(24, 24, 15, 11, 13, 5, "#819d49");

// Tiny pointed tail.
line(24, 39, 11, 24, 45, 9, 2, "#718d3f");
set(24, 46, 9, "#819d49");

// Wide, flat shell rim.
for (let x = 4; x <= 44; x++) {
  for (let y = 6; y <= 44; y++) {
    const d = ((x - 24) / 20) ** 2 + ((y - 25) / 19) ** 2;
    if (d > 1) continue;
    for (let z = 12; z <= 15; z++) {
      let color = z === 12 ? "#35472a" : "#496332";
      if (d > 0.87) color = z === 15 ? "#765936" : "#59452d";
      else if (d > 0.72) color = z === 15 ? "#658440" : "#405c31";
      else if (z === 15) color = "#527439";
      set(x, y, z, color);
    }
  }
}

// Domed shell with a tessellation of brown-outlined green hexagonal plates.
function plateAt(x, y) {
  let first = Infinity, second = Infinity, chosen = 0;
  for (let row = -2; row <= 5; row++) {
    const cy = 12 + row * 7.8;
    for (let col = -3; col <= 4; col++) {
      const cx = 10 + col * 9 + (Math.abs(row) % 2) * 4.5;
      const d = Math.hypot(x - cx, y - cy);
      if (d < first) {
        second = first;
        first = d;
        chosen = row * 17 + col;
      } else if (d < second) {
        second = d;
      }
    }
  }
  return { edge: second - first < 1.15, chosen };
}

for (let x = 7; x <= 41; x++) {
  for (let y = 8; y <= 42; y++) {
    const d = ((x - 24) / 17) ** 2 + ((y - 25) / 16) ** 2;
    if (d > 1) continue;
    const top = Math.round(15 + 17 * Math.sqrt(1 - d));
    const plate = plateAt(x, y);
    const shade = ["#649844", "#72a34a", "#79a950", "#60913e"][
      Math.abs(plate.chosen * 7 + 19) % 4
    ];

    for (let z = 16; z <= top; z++) {
      let color = z < top - 2 ? "#35552e" : shade;
      if (z < 20 && z < top - 1) color = "#405e30";
      if (z >= top - 2 && plate.edge) color = "#705535";
      if (z === top && !plate.edge && rand() < 0.065)
        color = "#87b35a";
      set(x, y, z, color);
    }
  }
}

// Each foot is a separate walking part.
function leg(name, x, y, speed) {
  part(name, [x, y, 11]);
  ellipsoid(x, y, 5, 5, 5, 6, "#728e40");
  ellipsoid(x, y - 2, 2, 5, 5, 2, "#829e49");

  // Broad toes and three little pale nails.
  for (const dx of [-3, 0, 3]) {
    ellipsoid(x + dx, y - 4, 2, 2, 2, 2, "#8da950");
    set(x + dx, y - 5, 1, "#c1b77a");
    set(x + dx, y - 5, 2, "#c8bf83");
  }
  // A couple of simple skin folds.
  line(x - 3, y, 8, x - 1, y + 1, 8, 0, "#5c7737");
  animate(name, { type: "swing", axis: "x", speed, amplitude: 0.2 });
}

leg("front-left", 12, 13, 3);
leg("front-right", 36, 13, -3);
leg("rear-left", 12, 36, -3);
leg("rear-right", 36, 36, 3);

// Big friendly head, attached at the neck.
part("head", [24, 14, 16]);
ellipsoid(24, 13, 15, 7, 6, 5, "#708d3d");
ellipsoid(24, 9, 16, 8, 7, 7, "#819e47");
ellipsoid(24, 7, 13, 6, 4, 3, "#90a950");

// Cheeks and a few short wrinkles.
ellipsoid(18, 7, 14, 2, 2, 2, "#8eaa4e");
ellipsoid(30, 7, 14, 2, 2, 2, "#8eaa4e");
line(17, 10, 17, 18, 12, 16, 0, "#607c38");
line(31, 10, 17, 30, 12, 16, 0, "#607c38");
line(18, 10, 13, 19, 12, 12, 0, "#647f38");
line(30, 10, 13, 29, 12, 12, 0, "#647f38");

// Black dot eyes with white glints.
for (const x of [20, 28]) {
  ellipsoid(x, 4, 19, 1.5, 1, 1.5, "#1d261b");
  set(x, 3, 20, "#ffffff");
}

// Tiny nostrils and a curved smile on the front of the muzzle.
set(22, 3, 15, "#526b36");
set(26, 3, 15, "#526b36");
set(21, 4, 12, "#455b30");
set(22, 3, 11, "#455b30");
line(23, 3, 11, 25, 3, 11, 0, "#455b30");
set(26, 3, 11, "#455b30");
set(27, 4, 12, "#455b30");

animate("head", { type: "bob", axis: "x", speed: 2, amplitude: 0.15 });
part("body", [24, 25, 12]);