fogón

← AnimalesObjeto 3Dfogon/delfin

Delfín

de fogonCC06689 bloques
DelfínArrastrá para girarlo
// «Delfín» · gpt-6-sol (medium)
// A cartoon bottlenose dolphin swimming, horizontal along y, head at the front (-y): a sleek smooth grey-blue body with a white belly, a short rounded beak with a smile, a black eye, a curved dorsal fin on top, two side flippers and a horizontal tail fluke at the back.

// A chunky bottlenose dolphin, swimming toward -y.
const blue = "#789bb0";
const lightBlue = "#91b5c7";
const shadowBlue = "#607f98";
const belly = "#edf4ef";
const bellyShade = "#d3e4e4";

// Rounded body, oversized head, and short beak.
ellipsoid(24, 23, 16, 8, 15, 8, blue);
ellipsoid(24, 13, 17, 8, 8, 8, blue);
ellipsoid(24, 36, 16, 4, 5, 4, blue);
ellipsoid(24, 7, 14, 5, 5, 3, blue);
ellipsoid(24, 7, 11, 5, 4, 2, belly);

// Broad white underside and softly varied blue back.
forEach((x, y, z) => {
  if (z <= 12 && y < 35) {
    set(x, y, z, z < 10 ? bellyShade : belly);
  } else if (z >= 19) {
    set(x, y, z, rand() < 0.11 ? blue : lightBlue);
  } else if (z < 15) {
    set(x, y, z, rand() < 0.08 ? blue : shadowBlue);
  } else if (rand() < 0.045) {
    set(x, y, z, lightBlue);
  }
});

// Curved, swept-back dorsal fin.
for (let z = 23; z <= 34; z++) {
  const t = z - 23;
  const front = Math.round(19 + t * 0.57);
  const back = Math.round(30 - t * 0.27);
  const halfWidth = Math.max(0, Math.round(3.5 - t * 0.29));
  for (let x = 24 - halfWidth; x <= 24 + halfWidth; x++) {
    for (let y = front; y <= back; y++) {
      set(x, y, z, x < 24 || z < 26 ? shadowBlue : blue);
    }
  }
}

// Side flippers sweep outward, backward, and gently downward.
for (const side of [-1, 1]) {
  for (let d = 0; d <= 14; d++) {
    const x = 24 + side * (8 + d);
    const cy = 22 + 0.48 * d;
    const cz = 11 - (11 / 14) * d;
    const ry = 3.6 * Math.pow(1 - d / 15, 0.7) + 0.35;
    const rz = 2.1 * Math.pow(1 - d / 15, 0.7) + 0.35;
    for (let y = Math.ceil(cy - ry); y <= Math.floor(cy + ry); y++) {
      for (let z = Math.max(0, Math.ceil(cz - rz)); z <= Math.floor(cz + rz); z++) {
        if (((y - cy) / ry) ** 2 + ((z - cz) / rz) ** 2 <= 1) {
          set(x, y, z, z >= cz ? lightBlue : shadowBlue);
        }
      }
    }
  }
}

// Simple dot eyes with tiny highlights.
for (const side of [-1, 1]) {
  const inner = 24 + side * 7;
  const outer = 24 + side * 8;
  box(Math.min(inner, outer), 10, 19, Math.max(inner, outer), 11, 20, "#253c4b");
  set(outer, 10, 20, "#ffffff");
}

// A little smile on each side of the beak.
for (const side of [-1, 1]) {
  set(24 + side * 4, 4, 12, "#536b77");
  set(24 + side * 5, 5, 12, "#536b77");
  set(24 + side * 5, 6, 12, "#536b77");
  set(24 + side * 5, 7, 13, "#536b77");
  set(24 + side * 5, 8, 13, "#536b77");
}
set(24, 2, 12, bellyShade);

// Horizontal tail fluke is the swimming part.
part("tail", [24, 39, 16]);
for (let d = 0; d <= 17; d++) {
  for (const side of d === 0 ? [1] : [-1, 1]) {
    const x = 24 + side * d;
    const front = Math.round(39 + 0.13 * d + 0.011 * d * d);
    const back = Math.round(44 + 0.11 * d);
    const thickness = Math.max(0, Math.round(2.2 * (1 - d / 18)));
    const centerZ = 16 + Math.round(d / 12);
    for (let y = front; y <= back; y++) {
      for (let z = centerZ - thickness; z <= centerZ + thickness; z++) {
        set(x, y, z, z >= centerZ ? lightBlue : shadowBlue);
      }
    }
  }
}
animate("tail", { type: "swing", axis: "x", speed: 4, amplitude: 0.35 });
part("body", [24, 24, 16]);