fogón

← Medieval3D assetfogon/puesto-de-mercado

Puesto de mercado

by fogonCC07842 blocks
Puesto de mercadoDrag to turn it
// «Puesto de mercado» · gpt-6-sol (medium)
// A medieval market stall: a dark brown timber frame with four posts holding a sloped striped awning in deep red and cream cloth, a wooden counter in front covered with small goods (red apples, yellow cheese wheels, round brown bread loaves, a couple of clay jugs), and two wicker baskets on the ground at the sides.

const timber = "#493020", timberLight = "#65422a", timberDark = "#301f18";
const iron = "#282a2b", gold = "#d2a64e";
const stone = ["#88847b", "#a09b8f", "#706f69"];
const wicker = "#a5743e", wickerLight = "#c29153", wickerDark = "#78502d";

// Uneven stone paving beneath the stall.
for (let x = 10; x <= 38; x++)
  for (let y = 12; y <= 37; y++) {
    set(x, y, 0, stone[Math.floor(rand() * stone.length)]);
    if (rand() < 0.025) set(x, y, 0, "#718063");
  }

// Four stout posts, with stone feet and iron straps.
for (const x of [9, 39]) for (const y of [11, 35]) {
  box(x - 1, y - 1, 0, x + 1, y + 1, 2, "#89857b");
  box(x - 1, y - 1, 3, x + 1, y + 1, y === 35 ? 32 : 27, timber);
  box(x - 1, y - 1, 5, x + 1, y + 1, 5, iron);
  box(x - 1, y - 1, 23, x + 1, y + 1, 23, iron);
  set(x, y - 2, 5, "#b3aaa0");
  set(x, y - 2, 23, "#b3aaa0");
  box(x - 1, y - 1, 3, x - 1, y - 1, y === 35 ? 32 : 27, timberLight);
}

// Heavy framing beneath the sloping awning.
line(9, 10, 27, 9, 36, 33, 1, timberDark);
line(39, 10, 27, 39, 36, 33, 1, timberDark);
box(9, 35, 30, 39, 36, 32, timber);
box(9, 10, 25, 39, 11, 27, timber);
box(9, 34, 15, 39, 35, 16, timberDark);
for (const x of [15, 33]) {
  line(x, 35, 17, x, 35, 30, 0, timberLight);
}

// Front counter: thick plank top, broad paneled front, and iron nails.
box(11, 11, 3, 12, 19, 12, timberDark);
box(36, 11, 3, 37, 19, 12, timberDark);
box(12, 12, 4, 36, 13, 11, timber);
for (let x = 16; x <= 33; x += 6)
  box(x, 11, 4, x, 11, 10, timberDark);
box(10, 10, 12, 38, 20, 14, timberDark);
box(10, 10, 14, 38, 20, 15, timberLight);
box(10, 10, 15, 38, 10, 15, "#815534");
for (let x = 13; x <= 36; x += 5) {
  set(x, 10, 6, iron);
  set(x, 10, 10, iron);
}
box(12, 13, 8, 36, 19, 8, timberLight);

// Rear display shelves and a little heraldic sign.
box(14, 31, 9, 34, 35, 10, timberLight);
box(14, 31, 16, 34, 35, 17, timberLight);
box(21, 34, 19, 27, 34, 24, gold);
box(22, 33, 20, 26, 33, 23, "#294c86");
box(24, 32, 20, 24, 32, 23, gold);
box(22, 32, 21, 26, 32, 21, gold);

// Bread: browned crust with a few pale score marks.
function bread(x, y, z, rx = 2, ry = 2) {
  ellipsoid(x, y, z, rx, ry, 1.7, "#85502c");
  ellipsoid(x, y, z + 1, rx - 0.3, ry - 0.3, 0.8, "#bd7d40");
  for (let dx = -1; dx <= 1; dx++)
    set(x + dx, y, z + 2, "#e2ad68");
}
for (const [x, y] of [[14, 14], [20, 16], [33, 16]])
  bread(x, y, 16);
for (const x of [17, 23, 30])
  bread(x, 32, 12, 2, 1.5);

// Small red apples with stems and leaves.
function apple(x, y, z) {
  sphere(x, y, z, 1.35, "#a72d2a");
  set(x, y - 1, z, "#cf5140");
  set(x, y, z + 2, timberDark);
  set(x + 1, y, z + 2, "#648244");
}
for (const [x, y] of [[25, 13], [28, 15], [31, 13], [26, 18], [30, 18]])
  apple(x, y, 17);

// Chunky yellow cheese wheels and cut wedges.
for (const [x, y] of [[16, 18], [35, 13]]) {
  cylinder(x, y, 16, 2, 2, "#c38a30");
  cylinder(x, y, 18, 2, 1, "#efd06b");
  set(x + 1, y - 1, 18, "#b98632");
}
box(34, 17, 16, 36, 19, 17, "#e9c45b");
set(36, 17, 17, "#b98632");

// Two clay jugs with narrow necks, lips, and angular handles.
function jug(x, y) {
  cylinder(x, y, 16, 1.7, 4, "#a66646");
  cylinder(x, y, 20, 1, 2, "#bc7d55");
  cylinder(x, y, 22, 1.4, 1, "#76452f");
  set(x, y, 22, "#382b26");
  line(x + 2, y, 19, x + 3, y, 19, 0, "#995b3b");
  line(x + 3, y, 19, x + 3, y, 21, 0, "#995b3b");
  line(x + 3, y, 21, x + 1, y, 21, 0, "#995b3b");
}
jug(15, 33);
jug(33, 33);

// Open-topped wicker baskets resting beside the stall.
function basket(cx, cy) {
  for (let z = 1; z <= 6; z++) {
    const r = z <= 2 ? 3 : 4;
    for (let dx = -r; dx <= r; dx++)
      for (let dy = -r; dy <= r; dy++) {
        const d = Math.sqrt(dx * dx + dy * dy);
        if (d <= r && (z <= 2 || d >= r - 1.25))
          set(cx + dx, cy + dy, z,
            (dx + dy + z) % 3 === 0 ? wickerLight : wicker);
      }
  }
  for (let z of [2, 4, 6])
    for (let dx = -4; dx <= 4; dx++)
      for (let dy = -4; dy <= 4; dy++) {
        const d = Math.sqrt(dx * dx + dy * dy);
        if (d >= 3.4 && d <= 4.35)
          set(cx + dx, cy + dy, z, z === 6 ? wickerLight : wickerDark);
      }
  box(cx - 2, cy - 2, 2, cx + 2, cy + 2, 3, wickerDark);
}
basket(5, 25);
basket(43, 25);
for (const [x, y] of [[4, 24], [7, 26], [42, 24], [44, 26]])
  apple(x, y, 6);

// The striped cloth alone pivots about its rear attachment.
part("awning", [24, 36, 33]);
const red = ["#922b31", "#a6383a", "#b54543"];
const cream = ["#e4d4ad", "#f1dfb9", "#d4c298"];
function clothColor(x, y) {
  const stripe = Math.floor((x - 7) / 5);
  const shades = stripe % 2 === 0 ? red : cream;
  return shades[rand() < 0.78 ? 0 : (rand() < 0.5 ? 1 : 2)];
}

for (let y = 8; y <= 37; y++) {
  const z = 26 + Math.floor((y - 8) / 5);
  for (let x = 7; x <= 41; x++) {
    set(x, y, z - 1, clothColor(x, y));
    set(x, y, z, clothColor(x, y));
    if (x === 7 || x === 41) set(x, y, z - 2, clothColor(x, y));
  }
}

// Deep scalloped fringe along the front, with golden tassel tips.
for (let x = 7; x <= 41; x++) {
  const stripe = Math.floor((x - 7) / 5);
  const drop = (x - 7) % 5 === 2 ? 4 : 3;
  for (let z = 26 - drop; z <= 25; z++)
    set(x, 7, z, clothColor(x, 7));
  if ((x - 7) % 5 === 2)
    set(x, 7, 25 - drop, stripe % 2 ? "#c6a35f" : gold);
}
animate("awning", { type: "swing", axis: "x", speed: 1.5, amplitude: 0.08 });