fogón

← Basics3D assetfogon/piano-de-cola

Piano de cola

by fogonCC09827 blocks
Piano de colaDrag to turn it
// «Piano de cola» · gpt-6-sol (medium)
// Grand piano («Piano de cola»).

// Grand piano, facing -y.
const black = "#101115";
const edge = "#08090c";
const gloss = "#202127";
const gold = "#a47b37";
const ivory = "#eee9db";

function sides(y) {
  const t = Math.max(0, Math.min(1, (y - 15) / 26));
  return [
    Math.round(8 + 10 * Math.pow(t, 1.35)),
    Math.round(39 - 9 * Math.pow(t, 0.8))
  ];
}

// Three sturdy piano legs, with brass-colored feet.
for (const [x, y] of [[12, 17], [35, 17], [25, 35]]) {
  box(x - 2, y - 2, 3, x + 2, y + 2, 19, black);
  box(x - 2, y - 2, 2, x + 2, y + 2, 4, gold);
  box(x - 1, y - 1, 0, x + 1, y + 1, 2, "#342a1a");
  box(x - 2, y - 2, 16, x + 2, y + 2, 19, gloss);
}

// Curved, solid grand-piano case.
for (let y = 15; y <= 41; y++) {
  const [l, r] = sides(y);
  for (let x = l; x <= r; x++) {
    for (let z = 19; z <= 25; z++) {
      const border = x <= l + 1 || x >= r - 1 || y >= 40;
      let c = border ? black : (z === 25 ? "#775727" : "#16171a");
      if (z === 25 && !border && rand() < 0.1) c = "#906d35";
      set(x, y, z, c);
    }
  }
  box(l, y, 22, l, y, 22, gold);
  box(r, y, 22, r, y, 22, "#654c29");
  box(l, y, 25, l + 1, y, 26, edge);
  box(r - 1, y, 25, r, y, 26, edge);
}
box(9, 14, 19, 38, 16, 24, black);
box(10, 14, 22, 37, 14, 22, "#775b30");

// A glimpse of the golden soundboard and strings beside the raised lid.
for (let x = 29; x <= 35; x += 2) {
  line(x, 20, 26, Math.min(x, 31), 36, 26, 0, "#c39a4a");
}
box(29, 22, 26, 30, 34, 26, "#332719");

// Raised lid: a long tapered wing, with narrow glossy ribs.
for (let y = 19; y <= 41; y++) {
  const [bodyL, bodyR] = sides(y);
  const l = bodyL;
  const r = Math.min(bodyR - 3, Math.round(31 - (y - 19) * 0.04));
  const height = Math.round(31 + (y - 19) * 0.48);
  for (let x = l; x <= r; x++) {
    const rib = (x - 8) % 3;
    const top = height + (rib === 0 ? 1 : 0);
    for (let z = height - 2; z <= top; z++) {
      let c = z < height ? "#101115" :
        rib === 0 ? "#292a30" : rib === 1 ? "#191a20" : "#0d0e12";
      if (x === l || x === r) c = edge;
      set(x, y, z, c);
    }
  }
}
// Visible dark edge of the lid and its slender gold prop.
line(10, 19, 29, 18, 40, 39, 1, "#090a0d");
line(31, 25, 26, 31, 25, 35, 0, "#b59558");
set(31, 25, 36, "#252226");

// Keyboard shelf and its projecting front lip.
box(9, 9, 19, 39, 15, 23, black);
box(10, 9, 20, 38, 9, 21, gloss);
box(10, 11, 24, 38, 16, 24, "#ded9ca");
for (let x = 11; x <= 37; x++) {
  box(x, 11, 25, x, 15, 25, x % 5 === 0 ? "#fffdf2" : ivory);
  set(x, 10, 24, "#bbb5a6");
  if (x < 37) box(x, 11, 25, x, 11, 25, "#77746d");
}
// Raised black keys, in repeating two-and-three groups.
for (let x = 12; x <= 36; x++) {
  if (![0, 3].includes((x - 12) % 7)) {
    box(x, 14, 26, x, 16, 26, "#0a0b0e");
    set(x, 14, 27, "#24252a");
  }
}
box(9, 10, 24, 10, 16, 26, edge);
box(38, 10, 24, 39, 16, 26, edge);
box(10, 16, 26, 38, 16, 27, black);

// Open music rest with two cream pages and tiny printed notes.
box(19, 17, 27, 36, 18, 28, black);
box(20, 18, 29, 35, 18, 35, edge);
box(21, 17, 30, 34, 17, 34, "#dcd5bd");
box(21, 17, 30, 27, 17, 34, "#f3eddc");
box(28, 17, 30, 34, 17, 34, "#e9e2cf");
box(27, 17, 30, 27, 17, 34, "#a59a7e");
for (const x of [23, 25, 29, 31, 33]) {
  set(x, 16, 31 + (x % 2), "#45413b");
  set(x + 1, 16, 31 + (x % 2), "#45413b");
  set(x + 1, 16, 33 + (x % 2), "#6b6458");
}
box(19, 17, 29, 19, 18, 36, edge);
box(35, 17, 29, 35, 18, 36, edge);
box(19, 17, 36, 35, 18, 36, black);

// Matching padded bench in front of the keyboard.
for (const x of [21, 37]) {
  for (const y of [3, 8]) {
    box(x - 1, y - 1, 1, x + 1, y + 1, 10, "#171719");
    box(x - 1, y - 1, 0, x + 1, y + 1, 2, "#a17a3a");
  }
}
box(19, 2, 10, 39, 9, 12, edge);
box(20, 3, 13, 38, 8, 13, "#24252a");
box(21, 4, 13, 37, 7, 13, "#2e2f34");
for (const [x, y] of [[25, 5], [31, 5], [36, 5], [28, 7], [34, 7]]) {
  set(x, y, 14, "#111216");
}
box(19, 2, 11, 39, 2, 12, gloss);