fogón

← Medieval3D assetfogon/cepo

Cepo

by fogonCC011574 blocks
CepoDrag to turn it
// «Cepo» · gpt-6-sol (medium)
// Medieval stocks: two thick wooden posts in the ground holding a horizontal plank board split in two halves with three round holes (a bigger one in the middle for the head, two smaller for the hands), black iron hinges and a padlock, on a small wooden platform.

const stone = ["#857e72", "#958d7f", "#aaa293", "#706b62"];
const wood = ["#765032", "#835b39", "#946a42", "#68452d"];
const darkWood = "#4b3124";
const iron = "#292b2c";
const ironLight = "#555759";

function holes(x, z, extra = 0) {
  return (
    Math.hypot(x - 15, z - 26) <= 2.55 + extra ||
    Math.hypot(x - 24, z - 26) <= 4.45 + extra ||
    Math.hypot(x - 33, z - 26) <= 2.55 + extra
  );
}

// Low stone footing, with a broad wooden deck and a step at the front.
box(4, 11, 0, 43, 38, 1, stone[0]);
for (let x = 4; x <= 43; x++) {
  for (let y = 11; y <= 38; y++) {
    if (rand() < 0.16) set(x, y, 1, stone[1 + Math.floor(rand() * 3)]);
  }
}
box(9, 8, 0, 38, 12, 1, stone[1]);
box(9, 9, 2, 38, 13, 2, "#725034");
box(6, 13, 2, 41, 36, 3, darkWood);

for (let y = 13; y <= 36; y += 4) {
  box(6, y, 4, 41, Math.min(y + 3, 36), 4, "#926941");
  line(6, y, 4, 41, y, 4, 0, "#b18855");
  for (let x = 8; x <= 39; x++) {
    if (rand() < 0.09) set(x, y + 2, 4, wood[Math.floor(rand() * wood.length)]);
  }
}
box(6, 13, 3, 41, 13, 4, "#b18a56");
box(6, 36, 3, 41, 36, 4, "#624329");
for (let x of [8, 19, 30, 40]) {
  set(x, 13, 4, "#493728");
  set(x, 36, 4, "#493728");
}

// Two massive upright posts. Their projecting feet brace them to the deck.
for (let [a, b] of [[8, 11], [37, 40]]) {
  box(a, 19, 4, b, 28, 35, "#684429");
  box(a - 1, 17, 4, b + 1, 30, 6, "#604028");
  box(a, 18, 6, b, 29, 8, "#795131");
  box(a - 1, 19, 35, b + 1, 28, 37, "#91683e");
  box(a - 1, 18, 36, b + 1, 18, 37, "#ad8150");
  box(a, 18, 9, a, 18, 34, "#a17444");
  box(b, 18, 9, b, 18, 34, "#513422");

  for (let z = 10; z <= 34; z++) {
    if (rand() < 0.27) set(a + 2, 18, z, "#805735");
    if (rand() < 0.13) set(a + 1, 18, z, "#4f3526");
  }
  for (let z of [12, 32]) {
    box(a, 17, z, b, 18, z + 1, iron);
    box(a + 1, 17, z + 1, b - 1, 17, z + 1, ironLight);
    set(a + 1, 16, z, "#9d9a88");
    set(b - 1, 16, z, "#9d9a88");
  }
}

// The two heavy halves of the stocks meet along the centers of the openings.
for (let x = 11; x <= 37; x++) {
  for (let y = 20; y <= 28; y++) {
    for (let z = 18; z <= 34; z++) {
      if (holes(x, z)) continue;
      let c = z >= 26 ? "#91673e" : "#805632";
      if (z === 34 || z === 26) c = "#ad7c48";
      if (z === 18 || z === 25) c = "#67432b";
      if (rand() < 0.075) c = wood[Math.floor(rand() * wood.length)];
      set(x, y, z, c);
    }
  }
}

// Dark, readable joint between the lifting upper half and fixed lower half.
for (let x = 12; x <= 36; x++) {
  if (!holes(x, 25)) set(x, 19, 25, "#3e2b22");
  if (!holes(x, 26)) set(x, 19, 26, "#ba8951");
}

// Rounded shadows at the cut edges of all three through-holes.
for (let x = 12; x <= 36; x++) {
  for (let z = 20; z <= 32; z++) {
    if (!holes(x, z) && holes(x, z, 1.05)) {
      set(x, 19, z, "#513425");
      if (z >= 27 && !holes(x, z)) set(x, 18, z, "#af7e49");
    }
  }
}

// Long grain, pegged ends, and a slight overhang on each plank.
for (let x = 12; x <= 36; x++) {
  if (!holes(x, 20) && x % 5 !== 0) set(x, 19, 20, "#966a40");
  if (!holes(x, 33) && x % 6 !== 0) set(x, 19, 33, "#b2844c");
}
for (let x of [12, 19, 29, 36]) {
  for (let z of [21, 30]) {
    if (!holes(x, z)) {
      set(x, 18, z, "#493322");
      set(x, 17, z, "#a78658");
    }
  }
}

// Black wrought-iron hinges on the left, with bright hammered rivets.
for (let z of [21, 29]) {
  box(10, 16, z, 13, 18, z + 2, iron);
  box(12, 15, z + 1, 14, 16, z + 1, ironLight);
  box(10, 15, z + 1, 11, 15, z + 1, "#77756b");
  set(13, 14, z + 1, "#aaa797");
}
box(10, 15, 24, 11, 17, 29, iron);
box(10, 14, 26, 11, 14, 27, ironLight);

// Iron hasp and substantial hanging padlock at the opposite end.
box(36, 16, 25, 40, 18, 27, iron);
box(37, 15, 27, 39, 16, 27, ironLight);
for (let x of [37, 40]) set(x, 15, 26, "#99978a");
box(37, 14, 21, 40, 16, 24, "#303233");
box(37, 13, 23, 40, 13, 24, ironLight);
box(38, 14, 25, 39, 15, 26, "#666866");
box(38, 13, 22, 39, 13, 23, "#444648");
set(38, 12, 22, "#bba46a");
set(38, 12, 21, "#bba46a");

// A few soft mossy flecks caught between stones, away from the timber.
for (let i = 0; i < 28; i++) {
  let x = 4 + Math.floor(rand() * 40);
  let y = 11 + Math.floor(rand() * 28);
  if (x < 7 || x > 40 || y < 14 || y > 35) {
    set(x, y, 1, rand() < 0.5 ? "#6b7959" : "#788362");
  }
}