fogón

← AsiáticoObjeto 3Dfogon/junco-chino

Junco chino

de fogonCC010214 bloques
Junco chinoArrastrá para girarlo
// «Junco chino» · gpt-6-sol (medium)
// A Chinese junk sailing ship: a curved brown wooden hull with a high raised stern, red and gold trim, two masts with big ribbed orange-red battened sails, a small cabin at the back, and a painted eye on the bow.

part("ship", [24, 24, 0]);

const woodDark = "#57301f";
const wood = "#79432a";
const woodLight = "#a56238";
const deck = "#bd8450";
const red = "#a82825";
const redLight = "#d44830";
const gold = "#edb94e";

function halfWidth(y) {
  if (y < 5) return 2 + (y - 2);
  if (y < 15) return 5 + Math.floor((y - 5) * 0.6);
  if (y < 35) return 11;
  return Math.max(4, 11 - Math.floor((y - 35) * 0.85));
}
function deckHeight(y) {
  return 12 + Math.max(0, Math.floor((9 - y) / 3))
            + Math.max(0, Math.floor((y - 33) / 3));
}

// Solid, curved hull with a rising bow and raised stern.
for (let y = 2; y <= 43; y++) {
  const w = halfWidth(y);
  const top = deckHeight(y);
  for (let x = 24 - w; x <= 24 + w; x++) {
    const edge = Math.abs(x - 24) / w;
    const bottom = 3 + Math.floor(4 * edge * edge) + (y < 6 ? 1 : 0);
    for (let z = bottom; z <= top; z++) {
      let color = z < 7 ? woodDark : wood;
      if (z >= top - 1) color = woodLight;
      if (z < top - 1 && rand() < 0.08) color = rand() < 0.5 ? woodDark : woodLight;
      set(x, y, z, color);
    }
    set(x, y, top, (y % 3 === 0) ? "#a56b40" : deck);
  }

  for (const side of [-1, 1]) {
    const x = 24 + side * w;
    box(x, y, top, x, y, top + 2, red);
    set(x, y, top + 1, redLight);
    set(x, y, top - 2, gold);
    if (y % 4 === 0 && y > 8 && y < 40) {
      box(x, y, top + 2, x, y, top + 4, woodDark);
      set(x, y, top + 4, gold);
    }
  }
}

// A narrow keel joins the underside of the hull and reaches the floor at z=0.
box(23, 11, 0, 25, 37, 3, woodDark);
box(23, 7, 2, 25, 10, 4, woodDark);
box(23, 38, 2, 25, 40, 4, woodDark);

// Horizontal hull planks and the sweeping lower gold accent.
for (let y = 8; y <= 40; y++) {
  const w = halfWidth(y);
  for (const side of [-1, 1]) {
    const x = 24 + side * w;
    const top = deckHeight(y);
    for (const z of [7, 10]) {
      if (z < top - 2) set(x, y, z, y % 5 === 0 ? "#c07842" : woodDark);
    }
    if (top > 10) set(x, y, top - 4, y % 6 === 0 ? "#ffe092" : gold);
  }
}

// Upturned carved prow and stern transom.
for (let y = 2; y <= 7; y++) {
  const h = 19 - Math.floor((y - 2) / 2);
  box(22, y, deckHeight(y), 26, y, h, y < 4 ? red : woodLight);
  box(23, y, h, 25, y, h, gold);
}
box(21, 2, 18, 27, 3, 19, red);
box(23, 1, 18, 25, 2, 19, gold);
for (let x = 19; x <= 29; x++) {
  if (Math.abs(x - 24) <= 4) {
    box(x, 42, 16, x, 43, 20, x % 2 ? woodLight : red);
    set(x, 43, 20, gold);
  }
}

// Painted eyes on both sides of the bow.
for (const side of [-1, 1]) {
  for (let y = 8; y <= 11; y++) {
    const x = 24 + side * halfWidth(y);
    box(x, y, 12, x, y, 14, "#fff0c5");
    set(x + side, y, 13, "#182d2a");
    if (y === 9) set(x + side, y, 14, gold);
  }
  const x = 24 + side * halfWidth(9);
  set(x + side, 9, 13, "#182d2a");
}

// Deck boards, raised stern steps, and ornamental posts.
for (let y = 12; y <= 40; y += 3) {
  const w = halfWidth(y) - 2;
  for (let x = 24 - w; x <= 24 + w; x++) {
    set(x, y, deckHeight(y), "#db9b5a");
  }
}
for (let y = 33; y <= 40; y++) {
  const z = deckHeight(y);
  box(19, y, z + 1, 29, y, z + 1, woodLight);
  if (y % 2 === 0) box(19, y, z + 1, 29, y, z + 1, deck);
}

// Small lacquered cabin at the stern.
box(19, 35, 18, 30, 41, 22, red);
box(20, 35, 19, 29, 35, 21, "#632d27");
for (const x of [21, 26]) {
  box(x, 34, 19, x + 2, 34, 21, gold);
  box(x + 1, 33, 19, x + 1, 33, 20, "#f6d490");
  set(x + 1, 33, 21, woodDark);
}
for (const x of [19, 30]) {
  box(x, 34, 18, x, 42, 23, redLight);
  box(x, 34, 23, x, 42, 23, gold);
}

// Glazed green tiled roof with upturned corners.
for (let x = 16; x <= 33; x++) {
  const d = Math.abs(x - 24.5);
  const z = 27 - Math.floor(d * 0.48);
  for (let y = 33; y <= 44; y++) {
    const edgeLift = (y === 33 || y === 44) ? 1 : 0;
    set(x, y, z + edgeLift, (x + y) % 3 === 0 ? "#457c65" : "#285648");
    set(x, y, z + edgeLift - 1, "#193e3a");
  }
}
box(23, 33, 28, 26, 44, 28, gold);
for (const x of [15, 34]) {
  for (let y = 33; y <= 44; y++) {
    set(x, y, 25 + ((y === 33 || y === 44) ? 1 : 0), "#3d7560");
  }
}
for (const x of [15, 34]) for (const y of [33, 44]) {
  set(x, y, 27, gold);
}

// Two tall dark masts.
box(23, 15, 13, 24, 16, 44, woodDark);
box(25, 28, 14, 26, 29, 39, woodDark);
for (let z = 17; z <= 43; z += 5) box(23, 14, z, 24, 17, z, gold);
for (let z = 18; z <= 38; z += 5) box(25, 27, z, 26, 30, z, gold);

// Ribbed junk sails.
function sail(mastY, low, high, leftSide) {
  for (let z = low; z <= high; z++) {
    const t = (z - low) / (high - low);
    const width = Math.round(13 + 6 * Math.sin(Math.PI * t));
    const near = leftSide ? 23 : 26;
    const far = leftSide ? near - width : near + width;
    const y = mastY - 2 - Math.round(t * 2);
    const lo = Math.min(near, far), hi = Math.max(near, far);
    for (let x = lo; x <= hi; x++) {
      const border = x === lo || x === hi || z === low || z === high;
      const rib = (z - low) % 4 === 0;
      let color = rib ? "#873327" : ((z + Math.floor(x / 4)) % 7 < 3 ? "#db6536" : "#e7773a");
      if (border) color = "#aa3828";
      if (!border && !rib && rand() < 0.075) color = "#f59a51";
      set(x, y, z, color);
      if (rib) set(x, y - 1, z, x % 5 === 0 ? gold : "#773525");
    }
    if ((z - low) % 4 === 0) {
      set(far, y - 1, z, gold);
      set(near, y - 1, z, gold);
    }
  }
}
sail(15, 22, 42, true);
sail(28, 21, 37, false);

// Yard ends, rigging, and golden mast finials.
for (const [my, lo, hi, left] of [[15, 22, 42, true], [28, 21, 37, false]]) {
  const near = left ? 23 : 26;
  for (let z = lo; z <= hi; z += 4) {
    const t = (z - lo) / (hi - lo);
    const w = Math.round(13 + 6 * Math.sin(Math.PI * t));
    const far = near + (left ? -w : w);
    line(near, my - 2 - Math.round(t * 2) - 1, z,
         far, my - 2 - Math.round(t * 2) - 1, z, 0, "#7b3325");
  }
}
box(23, 15, 44, 24, 16, 45, gold);
box(25, 28, 39, 26, 29, 40, gold);
line(24, 15, 43, 24, 5, 19, 0, "#e4bd75");
line(26, 29, 38, 31, 40, 20, 0, "#e4bd75");

animate("ship", { type: "bob", axis: "z", speed: 1, amplitude: 1 });