fogón

← Parties and Christmas3D assetfogon/trineo-con-regalos

Trineo con regalos

by fogonCC011715 blocks
Trineo con regalosDrag to turn it
// «Trineo con regalos» · gpt-6-sol (medium)
// Santa's sleigh seen from the side, horizontal along y with the front at -y: a red wooden body with gold curly trims, a high curved back, a dark green velvet seat, and two long golden runners curling up at the front. The back is loaded with a stack of colorful wrapped gifts and a brown sack.

// Santa's sleigh: front points toward -y.
const red = "#c82632", redLight = "#ed4050", redDark = "#941b2c";
const gold = "#f5bc37", goldLight = "#ffe07a", goldDark = "#b87924";
const green = "#14583d", greenLight = "#27845a", greenDark = "#0c3b30";
const wood = "#78442c";

function trim(points, radius, color) {
  for (let i = 1; i < points.length; i++) {
    line(...points[i - 1], ...points[i], radius, color);
  }
}

// Two long golden runners, resting on the floor at z = 0.
for (const x of [16, 32]) {
  box(x - 1, 7, 0, x + 1, 41, 2, goldDark);
  box(x - 1, 7, 3, x + 1, 41, 4, gold);
  box(x - 1, 8, 4, x, 40, 4, goldLight);

  // Upturned, curled front tips.
  trim([[x, 9, 3], [x, 6, 4], [x, 4, 7], [x, 4, 10],
        [x, 5, 12], [x, 7, 12], [x, 8, 10]], 1, gold);
  trim([[x, 4, 8], [x, 4, 10], [x, 5, 12], [x, 7, 12]], 0, goldLight);

  // A smaller flourish at the rear.
  trim([[x, 39, 3], [x, 42, 4], [x, 44, 6],
        [x, 44, 8], [x, 42, 9]], 1, gold);
  box(x - 1, 15, 5, x + 1, 17, 10, wood);
  box(x - 1, 32, 5, x + 1, 34, 10, wood);
  box(x - 1, 15, 8, x + 1, 17, 9, goldDark);
  box(x - 1, 32, 8, x + 1, 34, 9, goldDark);
}
box(16, 18, 3, 32, 19, 4, goldDark);
box(16, 35, 3, 32, 36, 4, goldDark);

// Wooden chassis and bright red sleigh tub.
box(16, 10, 9, 32, 39, 11, wood);
box(15, 10, 11, 33, 39, 14, redDark);
box(16, 11, 14, 32, 38, 15, redLight);
box(14, 13, 14, 16, 38, 19, red);
box(32, 13, 14, 34, 38, 19, red);
box(14, 14, 18, 16, 36, 19, redLight);
box(32, 14, 18, 34, 36, 19, redLight);

// Rounded rising prow.
for (let y = 9; y <= 14; y++) {
  const top = 23 - Math.floor((y - 9) * 0.8);
  box(15, y, 13, 33, y, top, y < 12 ? redLight : red);
}
box(16, 8, 16, 32, 9, 21, redDark);
box(17, 8, 20, 31, 8, 22, redLight);

// High, curved back with a thick gilded crest.
for (let y = 36; y <= 42; y++) {
  const height = [22, 25, 29, 32, 34, 33, 29][y - 36];
  box(15, y, 14, 33, y, height, red);
  box(16, y, height, 32, y, height, redLight);
}
box(16, 39, 32, 32, 40, 33, gold);
box(18, 40, 34, 30, 41, 34, goldLight);
box(15, 40, 27, 15, 42, 30, goldDark);
box(33, 40, 27, 33, 42, 30, goldDark);

// Velvet seat and padded backrest.
box(17, 15, 16, 31, 29, 18, greenDark);
box(18, 16, 18, 30, 29, 19, green);
box(19, 17, 19, 29, 27, 19, greenLight);
box(17, 30, 19, 31, 34, 23, greenDark);
box(18, 30, 21, 30, 33, 24, green);
box(19, 30, 24, 29, 31, 24, greenLight);

// Continuous gilded rims, visible from either side.
for (const x of [13, 35]) {
  line(x, 13, 20, x, 36, 20, 1, gold);
  line(x, 13, 21, x, 35, 21, 0, goldLight);
  trim([[x, 36, 20], [x, 38, 24], [x, 39, 29],
        [x, 40, 32], [x, 41, 32]], 1, gold);
  trim([[x, 13, 20], [x, 10, 23], [x, 8, 23],
        [x, 7, 21], [x, 9, 20]], 1, gold);
  // Curly side ornament, with a bright central stud.
  trim([[x, 17, 16], [x, 19, 14], [x, 23, 14],
        [x, 26, 16], [x, 30, 16], [x, 33, 14],
        [x, 35, 15]], 0, goldLight);
  sphere(x, 25, 16, 1, gold);
  set(x - (x < 24 ? 1 : -1), 25, 16, goldLight);
}

// Little brass studs along the outside panels.
for (const y of [16, 21, 29, 34]) {
  set(13, y, 18, goldLight);
  set(35, y, 18, goldLight);
}

// The whole cargo pile gently bounces together.
part("gifts", [24, 33, 24]);

// Sack tucked behind the parcels.
ellipsoid(25, 37, 25, 6, 4, 7, "#986039");
ellipsoid(24, 36, 27, 4, 3, 5, "#b47b48");
ellipsoid(25, 38, 33, 3, 2, 2, "#986039");
box(23, 37, 31, 27, 39, 32, gold);
line(25, 38, 32, 23, 36, 35, 0, "#d69b58");
line(25, 38, 32, 28, 37, 35, 0, "#d69b58");

function gift(x0, y0, z0, x1, y1, z1, base, top, ribbon) {
  box(x0, y0, z0, x1, y1, z1, base);
  box(x0, y0, z1, x1, y1, z1, top);
  // Crossed ribbon on the lid and on the front face.
  const mx = Math.floor((x0 + x1) / 2);
  const my = Math.floor((y0 + y1) / 2);
  box(mx, y0, z0, mx + 1, y1, z1 + 1, ribbon);
  box(x0, my, z1 + 1, x1, my, z1 + 1, ribbon);
  box(x0, y0 - 1, Math.floor((z0 + z1) / 2),
      x1, y0 - 1, Math.floor((z0 + z1) / 2), ribbon);
  // Oversized toy-like bow.
  set(mx - 2, my, z1 + 2, ribbon);
  set(mx - 1, my, z1 + 3, ribbon);
  set(mx, my, z1 + 2, goldLight);
  set(mx + 1, my, z1 + 3, ribbon);
  set(mx + 2, my, z1 + 2, ribbon);
}

gift(17, 28, 20, 23, 33, 25, "#eb719a", "#ffabc9", goldLight);
gift(25, 27, 20, 31, 33, 26, "#45bfc2", "#8be9df", "#fff3a2");
gift(17, 34, 24, 23, 38, 29, "#a678d6", "#d5b5f3", "#ffe07a");
gift(27, 33, 27, 32, 38, 32, "#eabf45", "#fff08e", "#e84c59");
gift(20, 29, 27, 26, 34, 31, "#40a960", "#75d781", "#ffe4a0");

animate("gifts", { type: "bob", axis: "z", speed: 3, amplitude: 1 });
part("body", [24, 24, 0]);