fogón

← Ancient and prehistory3D assetfogon/carro-egipcio

Carro egipcio

by fogonCC03613 blocks
Carro egipcioDrag to turn it
// «Carro egipcio» · gpt-6-sol (medium)
// An Egyptian war chariot: a light open cart of gold and wood with a curved front panel decorated with blue patterns, two big six-spoke wooden wheels on the sides, and a long pole sticking out forward (-y) with a yoke. No horse.

const wood = "#9b572b";
const woodLight = "#c47b38";
const woodDark = "#713d25";
const gold = "#e5ad39";
const goldLight = "#ffd66b";
const goldDark = "#ae7627";
const lapis = "#244c9b";
const blue = "#3778bd";
const turquoise = "#42c9c1";

const frontY = x => {
  const t = Math.abs(x - 24) / 8;
  return 16 + Math.round(4 * t * t);
};

// Axle, visible between the wheels.
box(10, 26, 10, 38, 28, 12, woodDark);
box(15, 26, 12, 33, 27, 13, goldDark);

// Shaped wooden floor: its front edge follows the curved shield.
for (let x = 16; x <= 32; x++) {
  for (let y = frontY(x); y <= 36; y++) {
    for (let z = 7; z <= 9; z++) {
      set(x, y, z, z === 9 ? woodLight : wood);
    }
    if (y > 21 && y < 35 && y % 4 === 0) set(x, y, 9, "#d08a42");
  }
}
for (let x = 16; x <= 32; x++) {
  set(x, 36, 8, goldDark);
  set(x, 36, 9, gold);
}
box(16, 35, 7, 32, 36, 7, woodDark);

// Curved, solid front shield, higher at its swept-back ends.
for (let x = 16; x <= 32; x++) {
  const y = frontY(x);
  const rise = Math.round(4 * Math.pow(Math.abs(x - 24) / 8, 2));
  const top = 19 + rise;
  for (let z = 10; z <= top; z++) {
    const c = z <= 11 ? goldDark : z === top ? goldLight : gold;
    set(x, y, z, c);
    set(x, y + 1, z, z < 12 ? woodDark : goldDark);
  }
  // Bright rim and a bold lapis stripe on the viewer-facing surface.
  set(x, y - 1, top, goldLight);
  set(x, y - 1, 11, goldLight);
  for (let z = 13; z <= 14; z++) set(x, y - 1, z, lapis);
  if (x % 3 === 0) set(x, y - 1, 14, turquoise);
}

// Turquoise lotus-and-sun ornament above the blue stripe.
for (let dx = -6; dx <= 6; dx++) {
  const x = 24 + dx, y = frontY(x) - 1;
  if (Math.abs(dx) <= 2) set(x, y, 16, turquoise);
  if (Math.abs(dx) === 3 || Math.abs(dx) === 4) set(x, y, 15, turquoise);
  if (Math.abs(dx) <= 1) set(x, y, 17, blue);
}
set(24, frontY(24) - 1, 18, goldLight);
for (const x of [18, 30]) {
  const y = frontY(x) - 1;
  set(x, y, 17, lapis);
  set(x, y, 18, turquoise);
}

// Open sides: low wooden guards with gilded top rails and rear posts.
for (const x of [16, 32]) {
  box(x, 22, 10, x, 35, 12, wood);
  box(x, 22, 13, x, 35, 13, goldDark);
  box(x, 23, 16, x, 35, 16, goldLight);
  for (const y of [24, 29, 34]) {
    box(x, y, 13, x, y, 16, gold);
    set(x, y, 15, turquoise);
  }
  box(x, 35, 10, x, 36, 18, goldDark);
  box(x, 35, 18, x, 36, 19, goldLight);
  set(x, 34, 19, lapis);
}

// Long central pole and broad, slightly swept yoke.
box(23, 3, 8, 25, 19, 9, wood);
box(24, 3, 10, 24, 18, 10, goldDark);
box(23, 1, 8, 25, 3, 9, gold);
box(24, 1, 9, 24, 2, 10, goldLight);

box(13, 4, 8, 35, 6, 9, woodLight);
box(13, 4, 10, 35, 5, 10, gold);
for (const x of [13, 14, 34, 35]) {
  box(x, 4, 8, x, 7, 11, gold);
  set(x, 4, 11, goldLight);
}
for (const x of [17, 20, 28, 31]) {
  box(x, 4, 10, x, 5, 10, lapis);
  set(x, 4, 11, turquoise);
}

// Each wheel is a separate spinning part. Their planes are perpendicular
// to the axle, so rotation around x rolls them forward.
function makeWheel(name, cx) {
  const cy = 27, cz = 11;
  part(name, [cx, cy, cz]);

  for (let x = cx - 2; x <= cx + 1; x++) {
    for (let y = cy - 11; y <= cy + 11; y++) {
      for (let z = 0; z <= 22; z++) {
        const r = Math.hypot(y - cy, z - cz);
        if (r >= 8.9 && r <= 11.1) {
          const outerFace = x === cx - 2 || x === cx + 1;
          set(x, y, z, outerFace ? woodLight : wood);
          if (outerFace && r > 10.25) set(x, y, z, gold);
          if (outerFace && r < 9.5) set(x, y, z, goldDark);
        }
      }
    }
  }

  // Six thick spokes, with gilded tips.
  for (let i = 0; i < 6; i++) {
    const a = i * Math.PI / 3;
    const dy = Math.cos(a), dz = Math.sin(a);
    line(cx, cy, cz, cx, cy + 9 * dy, cz + 9 * dz, 1, woodLight);
    line(cx - 1, cy + 7.5 * dy, cz + 7.5 * dz,
         cx - 1, cy + 9 * dy, cz + 9 * dz, 0, gold);
  }

  cylinder(cx - 2, cy, cz, 2, 4, goldDark, "x");
  cylinder(cx - 2, cy, cz, 1, 1, goldLight, "x");
  cylinder(cx + 1, cy, cz, 1, 1, goldLight, "x");

  // Rivets spaced around the outside face.
  const outside = cx < 24 ? cx - 2 : cx + 1;
  for (let i = 0; i < 12; i++) {
    const a = i * Math.PI / 6;
    set(outside, cy + 10 * Math.cos(a), cz + 10 * Math.sin(a), goldLight);
  }
  animate(name, { type: "spin", axis: "x", speed: 3 });
}

makeWheel("left wheel", 10);
makeWheel("right wheel", 39);
part("body");