fogón

← AsiáticoObjeto 3Dfogon/geisha

Geisha

de fogonCC012550 bloques
GeishaArrastrá para girarlo
// «Geisha» · gpt-6-sol (medium)
// A cartoon geisha standing facing front: a long flowing kimono in deep red with pink cherry blossom patterns and a wide gold obi sash with a big bow at the back, white face with small red lips and black dot eyes, tall black glossy hair bun with two red hairpins and a little flower, holding a small closed fan.

const red = ["#8f1830", "#a71d37", "#bb2943", "#ce3850"];
const gold = ["#ad711f", "#dc9b30", "#f4bd56"];
const pink = ["#f5a7b6", "#ffd1d5", "#e77f9b"];
const hair = ["#101018", "#1c1c27", "#30313d"];

function dressRadii(z) {
  if (z <= 4) return [15, 9];
  if (z <= 20) return [15 - (z - 4) * 0.38, 9 - (z - 4) * 0.19];
  if (z <= 26) return [9, 6];
  return [9 + (z - 26) * 0.23, 6 + (z - 26) * 0.1];
}
function frontY(x, z) {
  const [rx, ry] = dressRadii(z);
  const t = 1 - ((x - 24) / rx) ** 2;
  return Math.round(24 - ry * Math.sqrt(Math.max(0, t)));
}

// Broad, gently tapered kimono.
for (let z = 0; z <= 30; z++) {
  const [rx, ry] = dressRadii(z);
  for (let x = Math.ceil(24 - rx); x <= Math.floor(24 + rx); x++) {
    for (let y = Math.ceil(24 - ry); y <= Math.floor(24 + ry); y++) {
      if (((x - 24) / rx) ** 2 + ((y - 24) / ry) ** 2 > 1) continue;
      let shade = y < 23 ? 2 : 1;
      if (y > 27 || z < 3) shade = 0;
      if (y < 20 && z > 8 && rand() < 0.12) shade = 3;
      set(x, y, z, red[shade]);
    }
  }
}

// Weighted hem, with a narrow golden edge.
for (let z = 0; z <= 2; z++) {
  const [rx] = dressRadii(z);
  for (let x = Math.ceil(24 - rx); x <= Math.floor(24 + rx); x++) {
    const y = frontY(x, z);
    if (get(x, y, z)) set(x, y - 1, z, z === 1 ? "#d58b39" : "#79162a");
  }
}

// The wide obi wraps around the waist.
for (let z = 20; z <= 25; z++) {
  const [rx, ry] = dressRadii(z);
  for (let x = Math.ceil(24 - rx); x <= Math.floor(24 + rx); x++) {
    for (let y = Math.ceil(24 - ry); y <= Math.floor(24 + ry); y++) {
      if (!get(x, y, z)) continue;
      const edge = z === 20 || z === 25;
      set(x, y, z, edge ? "#ad711f" : y <= 22 ? gold[2] : gold[1]);
    }
  }
}
for (let z = 21; z <= 24; z++) {
  for (let x = 18; x <= 30; x++) {
    const y = frontY(x, z);
    set(x, y - 1, z, z === 22 ? "#ffe09a" : "#e7a63d");
  }
}

// Oversized bow: its loops peek out around both sides.
box(11, 29, 22, 19, 34, 28, "#c98829");
box(12, 30, 24, 18, 35, 27, "#f2b64e");
box(29, 29, 22, 37, 34, 28, "#bd7c25");
box(30, 30, 24, 36, 35, 27, "#efad41");
box(21, 34, 22, 27, 38, 27, "#d9942f");
box(22, 37, 23, 26, 39, 26, "#ffe095");

// Fixed sleeve, hanging from her left shoulder.
for (let z = 19; z <= 29; z++) {
  const lo = z < 23 ? 9 : z < 27 ? 11 : 14;
  const hi = z < 23 ? 16 : 17;
  box(lo, 19, z, hi, 28, z, z < 21 ? "#94192e" : z < 27 ? "#b32640" : "#c9344b");
}
box(9, 18, 19, 16, 28, 20, "#e2778a");
box(10, 18, 20, 15, 18, 20, "#ffd0c9");
box(12, 18, 24, 14, 18, 25, "#f0a0ae");

// Kimono overlap and pale V-shaped collar.
for (let z = 26; z <= 31; z++) {
  const spread = Math.floor((31 - z) * 0.72);
  for (const x of [22 - spread, 26 + spread]) {
    const y = frontY(x, Math.min(z, 30));
    box(x, y - 2, z, x + 1, y - 1, z, "#fff0dc");
  }
}
for (let z = 26; z <= 30; z++) {
  const x = 26 + Math.floor((30 - z) * 0.65);
  const y = frontY(x, z);
  set(x + 1, y - 2, z, "#e993a5");
}

// Blossom clusters on the front of the skirt.
function blossom(cx, cz) {
  const petals = [[0, 2], [-2, 0], [2, 0], [0, -2],
                  [-1, 1], [1, 1], [-1, -1], [1, -1]];
  for (const [dx, dz] of petals) {
    const x = cx + dx, z = cz + dz;
    if (z < 3 || z > 18) continue;
    const y = frontY(x, z);
    if (get(x, y, z)) set(x, y - 1, z, pink[(dx + dz + 12) % 3]);
  }
  const y = frontY(cx, cz);
  set(cx, y - 2, cz, "#f6c962");
}
for (const [x, z] of [
  [13, 7], [20, 12], [31, 6], [35, 13], [27, 17],
  [16, 17], [23, 5], [10, 14]
]) blossom(x, z);

// Neck and porcelain face.
box(22, 19, 29, 26, 25, 33, "#f5dfd2");
ellipsoid(24, 23, 35, 7, 6, 7, "#15151e");
ellipsoid(24, 18, 35, 5.5, 2.5, 6, "#fff0e4");
for (let z = 33; z <= 39; z++) {
  box(17, 17, z, 19, 22, z, hair[0]);
  box(29, 17, z, 31, 22, z, hair[0]);
}
box(19, 17, 40, 29, 22, 41, "#15151e");
box(21, 16, 40, 27, 17, 40, "#30313d");

// Small, clear facial features.
box(20, 15, 36, 21, 15, 37, "#191820");
box(27, 15, 36, 28, 15, 37, "#191820");
set(24, 15, 34, "#f5d9cc");
box(23, 15, 32, 25, 15, 32, "#b92739");
set(24, 14, 32, "#e84854");
set(17, 18, 32, "#f3bf57");
set(31, 18, 32, "#f3bf57");

// Glossy tall bun and lacquer-red hairpins.
ellipsoid(24, 24, 43, 5, 4, 3, hair[0]);
ellipsoid(23, 21, 45, 2, 2, 1, hair[2]);
line(27, 19, 43, 38, 19, 43, 0, "#bc2738");
line(27, 21, 45, 36, 21, 45, 0, "#e2474f");
set(37, 19, 43, "#f5bd55");
set(35, 21, 45, "#f5bd55");

// A little cherry flower tucked into the other side.
for (const [dx, dz] of [[0, 2], [-2, 0], [2, 0], [0, -2], [-1, 1], [1, 1]]) {
  set(18 + dx, 16, 42 + dz, dx === 0 ? "#ffd5d8" : "#f3a0b3");
}
set(18, 15, 42, "#efbc51");

// Fan arm is the only moving part.
part("fan arm", [32, 23, 29]);
box(31, 20, 27, 35, 26, 29, "#b52640");
for (let z = 18; z <= 27; z++) {
  const left = z < 22 ? 35 : 33;
  const right = z < 22 ? 40 : 38;
  box(left, 18, z, right, 26, z, z < 21 ? "#94192f" : "#b92743");
}
box(35, 17, 18, 40, 26, 19, "#e88a9a");
box(37, 17, 20, 39, 17, 21, "#ffd0cc");
box(38, 16, 18, 40, 19, 20, "#f6e0d2");

// Closed fan: a slim cream-and-gold wedge in her hand.
line(39, 16, 20, 43, 14, 26, 1, "#b68139");
line(40, 15, 20, 44, 13, 26, 1, "#fff0d6");
line(41, 15, 21, 44, 13, 26, 0, "#e2b15b");
set(44, 13, 27, "#da4d5a");
animate("fan arm", { type: "swing", axis: "y", speed: 2, amplitude: 0.3 });