fogón

← Medieval3D assetfogon/tienda-de-caballeros

Tienda de caballeros

by fogonCC07741 blocks
Tienda de caballerosDrag to turn it
// «Tienda de caballeros» · gpt-6-sol (medium)
// A round medieval knights' tournament tent: a cylindrical cloth wall with vertical stripes in deep red and cream, a conical striped roof with a scalloped hanging trim in gold, a tall pole on top with a blue pennant, and an open triangular front flap tied back showing a dark interior. A heraldic shield (blue with a gold lion) hangs beside the entrance.

const C = { x: 24, y: 24 };
const red = ["#80242e", "#982f37", "#ab3d42"];
const cream = ["#d9c69e", "#ead9b3", "#f3e5c3"];
const gold = "#d5a94d";
const goldLight = "#f0cf73";
const goldDark = "#9d6d30";

function stripe(x, y) {
  let a = Math.atan2(y - C.y, x - C.x);
  return Math.floor((a + Math.PI) / (2 * Math.PI) * 16) % 2;
}
function cloth(x, y, z, roof = false) {
  const pale = stripe(x, y);
  const n = rand();
  if (pale) return n < 0.12 ? cream[0] : n > 0.85 || roof && z > 27 ? cream[2] : cream[1];
  return n < 0.13 ? red[0] : n > 0.86 || roof && z > 27 ? red[2] : red[1];
}
function frontY(x) {
  const dx = x - C.x;
  return Math.round(C.y - Math.sqrt(Math.max(0, 16.5 * 16.5 - dx * dx)));
}

// A low, woven floor.
for (let x = 6; x <= 42; x++) for (let y = 6; y <= 42; y++) {
  const d = Math.hypot(x - C.x, y - C.y);
  if (d <= 16.7) {
    set(x, y, 0, d > 15.5 ? "#64432d" :
      (x + Math.floor(y / 3)) % 5 === 0 ? "#a88759" : "#98784c");
  }
}

// Cylindrical canvas wall. The widening opening makes a pointed doorway.
for (let z = 1; z <= 19; z++) {
  for (let x = 6; x <= 42; x++) for (let y = 6; y <= 42; y++) {
    const d = Math.hypot(x - C.x, y - C.y);
    if (d < 14.5 || d > 16.7) continue;
    const opening = y < C.y &&
      Math.abs(x - C.x) < 6.7 * (1 - z / 19.5);
    if (opening) continue;
    set(x, y, z, cloth(x, y, z));
  }
}

// A recessed, shadowy interior, visible through the doorway.
for (let z = 1; z <= 17; z++) {
  const half = Math.max(0, Math.floor(6.2 * (1 - z / 19)));
  for (let x = C.x - half; x <= C.x + half; x++) {
    for (let y = 12; y <= 13; y++)
      set(x, y, z, (x + z) % 7 === 0 ? "#342a26" : "#211c20");
  }
}
box(21, 12, 1, 21, 12, 10, "#4b3429");
box(27, 12, 1, 27, 12, 10, "#4b3429");

// Folded-back flaps follow the sloping edges of the open canvas.
for (let z = 2; z <= 17; z++) {
  const w = 6.7 * (1 - z / 19.5);
  for (const side of [-1, 1]) {
    const edgeX = Math.round(C.x + side * w);
    const y = frontY(edgeX) - 1;
    set(edgeX, y, z, z % 4 === 0 ? "#c04b45" : "#a83239");
    set(edgeX + side, y, z, "#76242d");
    if (z < 12 && z > 4)
      set(edgeX - side, y - 1, z,
        z % 3 === 0 ? "#e8d5ad" : "#d4bc92");
  }
}
// Ropes gathering the flaps at the waist.
for (const side of [-1, 1]) {
  const x = 24 + side * 4;
  line(x, frontY(x) - 3, 9, x + side * 3, frontY(x + side * 3) - 2, 11, 0, goldLight);
  box(x + side, frontY(x) - 4, 9, x + side, frontY(x) - 3, 10, goldDark);
}

// Conical roof, with the stripes continuing up from the walls.
for (let z = 20; z <= 35; z++) {
  const radius = 18.7 * (35.5 - z) / 15.5;
  for (let x = 5; x <= 43; x++) for (let y = 5; y <= 43; y++) {
    const d = Math.hypot(x - C.x, y - C.y);
    if (d <= radius && d >= Math.max(0, radius - 2.1))
      set(x, y, z, cloth(x, y, z, true));
  }
}

// Overhanging, scalloped gold valance.
for (let x = 5; x <= 43; x++) for (let y = 5; y <= 43; y++) {
  const d = Math.hypot(x - C.x, y - C.y);
  if (d < 17.3 || d > 19.1) continue;
  const angle = Math.atan2(y - C.y, x - C.x);
  const scallop = Math.cos(angle * 24);
  const bottom = scallop > 0.35 ? 16 : scallop > -0.5 ? 17 : 18;
  for (let z = bottom; z <= 20; z++)
    set(x, y, z, z === bottom ? goldDark :
      z === 19 || z === 20 ? goldLight : gold);
}

// Roof peak and tall, iron-bound wooden flagpole.
cylinder(24, 24, 34, 2, 3, goldDark);
box(24, 24, 36, 24, 24, 44, "#513323");
for (const z of [36, 40, 43]) set(24, 23, z, "#29292c");
set(24, 24, 45, goldLight);

// A shield hanging just to the right of the entrance.
line(34, 12, 18, 34, 9, 18, 0, "#3d2923");
for (let z = 7; z <= 18; z++) {
  const half = z >= 12 ? 3 : z >= 9 ? 2 : z === 8 ? 1 : 0;
  for (let x = 34 - half; x <= 34 + half; x++) {
    set(x, 10, z, "#392a28");
    set(x, 9, z, "#214c88");
    if (x === 34 - half || x === 34 + half || z === 18 || z === 7)
      set(x, 8, z, z === 18 ? goldLight : gold);
    else set(x, 8, z, "#245899");
  }
}
// Chunky, rearing gold lion: head, mane, body, paws and curling tail.
for (const [x, z] of [
  [33, 16], [34, 16], [32, 15], [33, 15], [34, 15],
  [33, 14], [34, 14], [35, 14], [34, 13], [35, 13],
  [34, 12], [35, 12], [33, 11], [35, 11],
  [36, 14], [37, 15], [36, 16]
]) set(x, 7, z, z === 16 ? goldLight : gold);
set(32, 7, 16, "#422b27");

// Canvas pegs and side guy ropes.
for (const side of [-1, 1]) {
  const sx = 24 + side * 15;
  const ex = 24 + side * 21;
  line(sx, 24, 19, ex, 24, 1, 0, "#b89459");
  box(ex, 23, 0, ex, 25, 2, "#634630");
  set(ex, 24, 3, "#302b29");
}

// The pennant alone pivots around its fastening on the pole.
part("pennant", [24, 24, 42]);
for (let x = 25; x <= 38; x++) {
  const halfHeight = x < 31 ? 2 : x < 36 ? 1 : 0;
  const y = 24 + (x >= 33 ? 1 : 0);
  for (let z = 42 - halfHeight; z <= 42 + halfHeight; z++) {
    set(x, y, z, z === 42 + halfHeight ? "#5286c5" :
      (x + z) % 4 === 0 ? "#173e80" : "#245ba4");
  }
}
set(25, 23, 42, goldLight);
set(38, 25, 42, goldLight);
animate("pennant", { type: "swing", axis: "z", speed: 3, amplitude: 0.3 });
part("body", [24, 24, 0]);