fogón

← AsiáticoObjeto 3Dfogon/carpa-koi-gigante

Carpa koi gigante

de fogonCC013431 bloques
Carpa koi giganteArrastrá para girarlo
// «Carpa koi gigante» · gpt-6-sol (medium)
// A big chunky koi fish swimming horizontally along y, raised slightly off the ground: a plump white body with large orange-red patches and a few black spots, big flowing fins, a round mouth with two short whiskers at the front (-y), black dot eyes, a wide fan tail at the back.

const pearl = "#fff2d8";
const warmWhite = "#f3e1bf";
const shadowWhite = "#d6c5a9";
const orange = "#ef722d";
const vermilion = "#c94326";
const deepRed = "#a63426";
const gold = "#f5b957";
const ink = "#242a29";

// Shallow jade-green pool. Place its floor block by block at z=0.
part("pool", [24, 23, 0]);
for (let x = 8; x <= 40; x++) {
  for (let y = 6; y <= 40; y++) {
    const d = ((x - 24) / 16) ** 2 + ((y - 23) / 17) ** 2;
    if (d <= 1) {
      set(x, y, 0, d > 0.78 ? "#376b64" : "#579e96");
    }
  }
}
for (let a = 0; a < Math.PI * 2; a += 0.08) {
  const x = Math.round(24 + Math.cos(a) * 11);
  const y = Math.round(23 + Math.sin(a) * 12);
  if (Math.sin(a * 7) > -0.3) set(x, y, 1, "#9cc9b2");
}

// Plump koi, swimming above the pool.
part("body", [24, 24, 20]);
ellipsoid(24, 22, 20, 12, 16, 10, warmWhite);
ellipsoid(24, 21, 21, 11, 15, 9, pearl);
ellipsoid(24, 9, 20, 7, 5, 6, pearl);

// Shade the body and paint broad koi markings.
forEach((x, y, z, color) => {
  if (color !== pearl && color !== warmWhite) return;
  let c = z < 16 ? shadowWhite : z > 26 ? "#fff8e9" : pearl;
  const patch1 = ((x - 25) ** 2 / 115 + (y - 17) ** 2 / 38 + (z - 29) ** 2 / 85) < 1;
  const patch2 = ((x - 21) ** 2 / 120 + (y - 30) ** 2 / 31 + (z - 28) ** 2 / 75) < 1;
  const sidePatch = ((x - 13) ** 2 / 28 + (y - 25) ** 2 / 31 + (z - 20) ** 2 / 40) < 1;
  const headBlaze = y < 15 && z > 25 && x > 20 && x < 29;

  if (patch1 || patch2 || sidePatch || headBlaze) {
    c = z > 27 ? orange : vermilion;
    if (rand() < 0.12) c = "#db5729";
  } else if (rand() < 0.035) {
    c = "#e8d5b6";
  }
  set(x, y, z, c);
});

// Distinct black spots.
ellipsoid(35, 23, 23, 1, 3, 2, ink);
ellipsoid(15, 16, 25, 2, 2, 1, ink);
ellipsoid(27, 34, 26, 2, 2, 1, ink);

// High, swept dorsal fin.
for (let y = 18; y <= 36; y++) {
  const peak = Math.max(0, 10 - Math.abs(y - 27) * 0.8);
  const base = 28 + Math.max(0, (y - 31) * 0.3);
  for (let z = Math.ceil(base); z <= Math.floor(30 + peak); z++) {
    const halfWidth = z > 35 ? 1 : 2;
    for (let x = 24 - halfWidth; x <= 24 + halfWidth; x++) {
      set(x, y, z, z >= 29 + peak ? gold : y % 4 === 0 ? orange : vermilion);
    }
  }
}
line(24, 18, 29, 24, 27, 40, 1, gold);

// Broad pectoral fins swept back and down.
for (const side of [-1, 1]) {
  const rootX = 24 + side * 10;
  ellipsoid(rootX, 18, 17, 3, 5, 3, vermilion);
  for (let reach = 0; reach <= 9; reach++) {
    const x = rootX + side * reach;
    const centerY = 19 + reach * 0.65;
    const centerZ = 17 - reach * 0.9;
    const spread = 2 + reach * 0.45;
    for (let y = Math.ceil(centerY - spread); y <= Math.floor(centerY + spread); y++) {
      for (let z = Math.ceil(centerZ - 1); z <= Math.floor(centerZ + 1); z++) {
        set(x, y, z,
          reach > 7 || Math.abs(y - centerY) > spread - 1 ? gold : orange);
      }
    }
  }
  line(rootX, 18, 17, rootX + side * 9, 24, 9, 0, deepRed);
}

// Small paired pelvic fins.
for (const side of [-1, 1]) {
  line(24 + side * 7, 29, 14, 24 + side * 12, 33, 8, 2, orange);
  line(24 + side * 8, 30, 13, 24 + side * 13, 35, 8, 0, gold);
}

// Round, forward-facing mouth with soft white lips.
ellipsoid(24, 6, 19, 5, 3, 5, warmWhite);
for (let x = 19; x <= 29; x++) {
  for (let z = 14; z <= 24; z++) {
    const d = ((x - 24) / 4.5) ** 2 + ((z - 19) / 4.5) ** 2;
    if (d < 0.48) set(x, 3, z, deepRed);
    else if (d < 1.05 && d > 0.43) {
      set(x, 3, z, z >= 20 ? pearl : warmWhite);
      if (d > 0.7) set(x, 4, z, pearl);
    }
  }
}
set(23, 3, 20, "#682b29");
set(24, 3, 20, "#682b29");
set(25, 3, 20, "#682b29");

// Glossy eyes and short curling whiskers.
for (const side of [-1, 1]) {
  const ex = 24 + side * 8;
  ellipsoid(ex, 11, 23, 2, 2, 2, gold);
  sphere(ex + side, 10, 23, 1, ink);
  set(ex + side, 9, 24, "#ffffff");

  line(24 + side * 4, 4, 17, 24 + side * 7, 2, 15, 1, warmWhite);
  line(24 + side * 7, 2, 15, 24 + side * 9, 2, 13, 0, gold);
}
animate("body", { type: "bob", axis: "z", speed: 1.3, amplitude: 1 });

// Separate swinging fan tail.
part("tail", [24, 37, 20]);
ellipsoid(24, 36, 20, 5, 5, 5, pearl);
for (let y = 38; y <= 45; y++) {
  const t = y - 38;
  const width = 5 + t * 2;
  for (let x = 24 - width; x <= 24 + width; x++) {
    const side = Math.abs(x - 24) / width;
    const height = (4 + t * 0.95) * Math.sqrt(Math.max(0, 1 - side * side * 0.72));
    for (let z = Math.ceil(20 - height); z <= Math.floor(20 + height); z++) {
      if (y >= 44 && Math.abs(x - 24) <= y - 43 && z >= 17 && z <= 23) continue;
      const edge = Math.abs(z - 20) > height - 1 || side > 0.94;
      let color = edge ? gold : x % 5 === 0 ? "#dc592d" : orange;
      if (y >= 44 && rand() < 0.12) color = "#f39242";
      set(x, y, z, color);
    }
  }
}
for (const side of [-1, 1]) {
  line(24, 38, 20, 24 + side * 17, 45, 27, 0, deepRed);
  line(24, 38, 20, 24 + side * 17, 45, 13, 0, deepRed);
}
animate("tail", { type: "swing", axis: "z", speed: 4, amplitude: 0.4 });
animate("tail", { type: "bob", axis: "z", speed: 1.3, amplitude: 1 });