fogón

← Antiguo y prehistoriaObjeto 3Dfogon/hand-cart

Carro de mano

de fogonCC04993 bloques
Carro de manoArrastrá para girarlo
// «Carro de mano» · propio
// A two-wheeled wooden hand cart with low side boards, two big dark spoked wheels with iron hubs, two long handles resting towards the front, loaded with two burlap sacks.

// A two-wheeled wooden hand cart: low side boards, two big dark spoked wheels with iron hubs, two long handles that
// rest on the ground towards the front, and two burlap sacks in it.
const wood = ["#73492a", "#85562f", "#976639", "#a97645", "#b98652"];
const dark = ["#35251a", "#463222", "#57402c", "#684d36"];
const iron = ["#2b2928", "#3a3735", "#55504c"];
const burlap = ["#8a6c3f", "#9c7d4c", "#b0915c", "#c2a36c", "#d0b47e"];
const clampi = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
const X0 = 15, X1 = 33, Y0 = 17, Y1 = 41;
// The bed: planks along its length.
for (let x = X0; x <= X1; x++)
  for (let y = Y0; y <= Y1; y++) {
    const line = (x - X0) % 5 === 0 && x !== X0;
    set(x, y, 13, wood[1]);
    set(x, y, 14, line ? wood[0] : wood[clampi(2 + (Math.floor((x - X0) / 5) % 2) - (rand() < 0.15 ? 1 : 0), 0, 4)]);
  }
// Side boards and the back board: two planks high, with uprights.
for (let z = 15; z <= 21; z++) {
  const gap = z === 18;
  for (let y = Y0; y <= Y1; y++) for (const x of [X0, X1]) set(x, y, z, gap ? wood[0] : wood[clampi((z > 18 ? 3 : 2) + (x === X0 ? 1 : 0) - (rand() < 0.12 ? 1 : 0), 0, 4)]);
  for (let x = X0; x <= X1; x++) set(x, Y1, z, gap ? wood[0] : wood[clampi((z > 18 ? 3 : 2) - (rand() < 0.12 ? 1 : 0), 0, 4)]);
}
for (const y of [Y0 + 1, 29, Y1 - 1]) for (const x of [X0 - 1, X1 + 1]) box(x, y, 12, x, y + 1, 22, dark[2]);
// The axle and the wheels: a rim with an iron tyre, eight spokes and a hub.
box(11, 30, 9, 37, 31, 10, dark[1]);
const WY = 30.5, WZ = 10, WR = 10.5;
for (const wx of [11, 12, 36, 37])
  for (let y = Math.floor(WY - WR); y <= Math.ceil(WY + WR); y++)
    for (let z = 0; z <= Math.ceil(WZ + WR); z++) {
      const d = Math.hypot(y - WY, z - WZ);
      if (d > WR) continue;
      const outer = wx === 11 || wx === 37;
      if (d > WR - 1.1) set(wx, y, z, iron[z > WZ + 4 ? 2 : 1]);
      else if (d > WR - 3.2) set(wx, y, z, dark[clampi(2 + (z > WZ ? 1 : 0) - (rand() < 0.15 ? 1 : 0), 0, 3)]);
      else if (d < 2.4) set(wx, y, z, outer ? iron[2] : iron[1]);
      else {
        // Spokes: near one of eight directions.
        const a = Math.atan2(z - WZ, y - WY);
        const k = Math.round(a / (Math.PI / 4)) * (Math.PI / 4);
        if (Math.abs(Math.sin(a - k)) * d < 0.75) set(wx, y, z, dark[clampi(2 + (outer ? 1 : 0), 0, 3)]);
      }
    }
for (const wx of [10, 38]) box(wx, 30, 9, wx, 31, 10, iron[2]);
// The handles: from the bed down to the ground in front, with a bar to push by.
line(X0, Y0, 14, X0 - 1, 3, 0.4, 0.9, wood[3]);
line(X1, Y0, 14, X1 + 1, 3, 0.4, 0.9, wood[3]);
line(X0 - 1, 4, 1, X1 + 1, 4, 1, 0.5, dark[2]);
// A prop under the front of the bed.
box(23, Y0 + 2, 6, 24, Y0 + 3, 12, dark[1]);
// Two sacks.
function sack(cx, cy, cz, rx, ry, rz) {
  for (let x = Math.floor(cx - rx); x <= Math.ceil(cx + rx); x++)
    for (let y = Math.floor(cy - ry); y <= Math.ceil(cy + ry); y++)
      for (let z = Math.floor(cz - rz); z <= Math.ceil(cz + rz); z++) {
        const nx = (x - cx) / rx, ny = (y - cy) / ry, nz = (z - cz) / rz;
        if (Math.pow(Math.abs(nx), 2.5) + Math.pow(Math.abs(ny), 2.5) + Math.pow(Math.abs(nz), 2.5) > 1) continue;
        if (z < 15) continue;
        let tone = 2 + (nz > 0.4 ? 1 : 0) + (-nx - ny > 0.6 ? 1 : 0) - ((x + y + z) % 2 ? 0 : 1);
        set(x, y, z, Math.abs(x - cx) < 0.6 && nz > 0.3 ? "#6f5530" : burlap[clampi(tone, 0, 4)]);
      }
}
sack(24, 24, 19, 7.5, 6, 5);
sack(24.5, 34.5, 19.5, 7, 5.5, 5.5);
sphere(24, 17.5, 20, 1.6, burlap[3]);
box(23, 16, 19, 25, 16, 21, burlap[4]);