fogón

← AnimalesObjeto 3Dfogon/caballito-de-mar

Caballito de mar

de fogonCC06488 bloques
Caballito de marArrastrá para girarlo
// «Caballito de mar» · gpt-6-sol (medium)
// A cartoon seahorse standing upright facing sideways (snout toward -y): a curved yellow-orange body with ridged segments, a horse-like head with a long tube snout and a little crown, a big eye, a small back fin and a tail curling into a spiral at the bottom.

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

const gold = "#f6ad32";
const light = "#ffd257";
const shadow = "#d98122";

// Curled tail: a thick outer coil narrowing into a little spiral tip.
const tail = [
  [28, 17, 3.5], [32, 14, 3.2], [37, 12, 3.0],
  [40, 9, 2.8], [40, 5, 2.6], [37, 2, 2.4],
  [32, 2, 2.2], [28, 5, 2.0], [28, 9, 1.9],
  [32, 11, 1.7], [35, 9, 1.5], [35, 6, 1.3],
  [33, 6, 1.2]
];
for (let i = 0; i < tail.length - 1; i++) {
  const a = tail[i], b = tail[i + 1];
  line(24, a[0], a[1], 24, b[0], b[1], a[2] + 0.5, shadow);
  line(24, a[0], a[1] + 0.5, 24, b[0], b[1] + 0.5, a[2], gold);
}

// Fan-shaped dorsal fin, tucked behind the body.
const fin = [
  [29, 23], [37, 22], [35, 26], [41, 27],
  [36, 29], [39, 33], [32, 31], [29, 29]
];
function inFin(y, z) {
  let inside = false;
  for (let i = 0, j = fin.length - 1; i < fin.length; j = i++) {
    const a = fin[i], b = fin[j];
    if ((a[1] > z) !== (b[1] > z) &&
        y < (b[0] - a[0]) * (z - a[1]) / (b[1] - a[1]) + a[0]) {
      inside = !inside;
    }
  }
  return inside;
}
for (let x = 21; x <= 27; x++)
  for (let y = 29; y <= 41; y++)
    for (let z = 22; z <= 33; z++)
      if (inFin(y, z)) set(x, y, z, x === 27 ? "#ffbd49" : "#e88934");
for (const tip of [[37, 23], [40, 27], [38, 32]]) {
  line(27, 29, 27, 27, tip[0], tip[1], 0, "#ffd06a");
}

// Rounded, forward-curving torso and narrow neck.
ellipsoid(24, 26, 22, 7.5, 7.5, 10, shadow);
ellipsoid(24, 25, 25, 7.6, 7.1, 9.5, gold);
ellipsoid(24, 25, 31, 6, 5.5, 7, gold);
ellipsoid(24, 22, 35, 5.5, 5, 5.5, gold);

// A few subtle speckles on the large golden surfaces.
forEach((x, y, z, color) => {
  if (color === gold && rand() < 0.035)
    set(x, y, z, rand() < 0.5 ? "#f9b840" : "#e99a2b");
});

// Pale rounded belly; the raised ribs remain visible along both sides.
ellipsoid(24, 20, 23, 5.4, 3.8, 8.3, "#ffcf64");
for (const z of [18, 21, 24, 27, 30]) {
  for (const x of [17, 31]) {
    line(x, 23, z + 1, x, 29, z - 1, 0.8, "#dc8727");
    line(x + (x < 24 ? -1 : 1), 24, z + 2,
         x + (x < 24 ? -1 : 1), 28, z, 0, "#ffc149");
  }
}

// Oversized horse-like head and long tubular muzzle.
ellipsoid(24, 20, 38, 6.5, 6.5, 5.2, shadow);
ellipsoid(24, 19, 38.5, 6.3, 6.2, 5, gold);
ellipsoid(24, 18, 35, 5, 5.5, 3.5, "#f8b63e");
cylinder(24, 11, 34, 2.7, 9, gold, "y");
ellipsoid(24, 10, 33.5, 3.8, 2.4, 2.8, light);
box(22, 8, 31, 26, 9, 31, "#db8730");
set(21, 8, 34, "#aa6229");
set(27, 8, 34, "#aa6229");

// A tiny fin beside each cheek.
for (const x of [17, 31]) {
  ellipsoid(x, 27, 32, 1.6, 3.4, 2.2, "#ef9130");
  line(x, 27, 32, x, 30, 33, 0, "#ffd064");
}

// Crown-shaped crest with three distinct points.
box(22, 17, 41, 26, 26, 42, "#e98929");
box(22, 16, 42, 26, 18, 44, "#ffc34b");
box(22, 20, 42, 26, 22, 46, "#ffd65b");
box(22, 24, 42, 26, 26, 44, "#ffc34b");
box(23, 20, 46, 25, 22, 46, "#fff09b");

// Big, simple toy eyes, visible from either side.
for (const side of [-1, 1]) {
  const eyeX = 24 + side * 6;
  ellipsoid(eyeX, 17, 39, 1.5, 2.1, 2.1, "#fff1ba");
  ellipsoid(eyeX + side, 16, 39, 1.2, 1.5, 1.6, "#29272b");
  set(eyeX + side * 2, 15, 40, "#ffffff");
  ellipsoid(24 + side * 6, 19, 35, 1, 1.6, 0.8, "#ef8a39");
}

animate("body", { type: "bob", axis: "z", speed: 2, amplitude: 1.5 });