fogón

← Pirates and sea3D assetfogon/balsa

Balsa

by fogonCC07930 blocks
BalsaDrag to turn it
// «Balsa» · gpt-6-sol (medium)
// A castaway raft of eight round light-brown logs tied side by side with rope bands, a short mast made of a branch with a torn white cloth sail, a small barrel and a bunch of bananas on the deck.

const wood = ["#ad6d38", "#bb7a3d", "#c48645", "#b77439"];
const shadow = "#88502b";
const grain = "#d89a55";
const rope = "#e8c78a";

// Eight rounded logs, laid side by side.
for (let i = 0; i < 8; i++) {
  const x = 8 + i * 4.5;
  const base = wood[i % wood.length];

  cylinder(x, 5, 3, 2.7, 38, base, "y");

  // Dark undersides touch the floor at z = 0.
  line(x, 6, 0, x, 41, 0, 0, shadow);
  for (let y = 5; y <= 42; y++) {
    for (let dx = -2; dx <= 2; dx++) {
      if (get(x + dx, y, 1)) set(x + dx, y, 1, shadow);
    }
  }

  // Long, irregular weathered grain.
  for (let j = 0; j < 13; j++) {
    const yy = 7 + Math.floor(rand() * 33);
    const xx = x + (rand() < 0.5 ? -1 : 1);
    line(xx, yy, 6, xx, Math.min(yy + 2 + Math.floor(rand() * 5), 41), 6, 0, grain);
  }

  // Bright cut ends with dark growth-ring marks.
  for (const y of [5, 42]) {
    for (let dx = -2; dx <= 2; dx++) {
      for (let dz = -2; dz <= 2; dz++) {
        if (dx * dx + dz * dz <= 5)
          set(x + dx, y, 3 + dz, "#d99a55");
      }
    }
    set(x, y, 3, "#a96b38");
    set(x + 1, y, 3, "#b7793d");
  }
}

// Two rope bands wrap across all the logs.
for (const y of [12, 36]) {
  for (let dy = 0; dy <= 2; dy++) {
    line(5, y + dy, 7, 42, y + dy, 7, 0, dy === 1 ? "#f3d99d" : "#c99b59");
  }
  for (const x of [5, 42]) {
    line(x, y, 2, x, y, 7, 0, "#c99b59");
    line(x, y + 2, 2, x, y + 2, 7, 0, rope);
  }
}
sphere(39, 13, 8, 1.2, rope);
sphere(10, 37, 8, 1.2, rope);

// A stout, slightly crooked branch mast and its lashings.
cylinder(24, 25, 7, 1.6, 17, "#85502d");
line(24, 25, 23, 25, 25, 38, 1.1, "#a86d3b");
line(24, 25, 8, 25, 25, 39, 0, "#d29857");
for (const z of [9, 11, 21, 35]) {
  cylinder(24, 25, z, 1.9, 1, rope);
}

// Small toy-like barrel on the deck.
cylinder(15, 22, 7, 3, 9, "#a96231");
cylinder(15, 22, 15, 2.7, 1, "#d18b45");
for (let z = 8; z <= 15; z++) {
  for (let y = 19; y <= 25; y++) {
    if (get(12, y, z)) set(12, y, z, "#794527");
  }
}
for (const z of [9, 13]) {
  for (let a = 0; a < Math.PI * 2; a += 0.12) {
    set(15 + 3.15 * Math.cos(a), 22 + 3.15 * Math.sin(a), z, "#e6b659");
  }
}
set(15, 22, 16, "#80502d");
set(16, 22, 16, "#edb66b");

// A clustered bunch of curved, sunny yellow bananas.
sphere(33, 18, 9, 1.2, "#80622c");
for (let i = 0; i < 5; i++) {
  const side = i - 2;
  const y = 18 + side * 0.8;
  line(33, 18, 9, 34 + side * 0.75, y - 1, 10, 0.8, "#e8a824");
  line(34 + side * 0.75, y - 1, 10,
       36 + side * 0.9, y - 3, 9, 0.9, "#ffcf3e");
  line(36 + side * 0.9, y - 3, 9,
       37 + side * 0.8, y - 3.5, 10, 0.55, "#ffe16b");
  set(37 + side * 0.8, y - 3.5, 10, "#79512c");
}

// The sail and its spars pivot together at the masthead.
part("sail", [25, 23, 37]);

line(25, 23, 36, 38, 21, 31, 0.65, "#a46c3a");
line(25, 23, 16, 41, 21, 18, 0.55, "#a46c3a");

for (let z = 16; z <= 35; z++) {
  let right;
  if (z >= 31) right = 25 + (36 - z) * 2.6;
  else if (z <= 19) right = 26 + (z - 15) * 3.7;
  else right = 41 - (z - 19) * 0.23;

  for (let x = 26; x <= Math.floor(right); x++) {
    // Ragged lower hem, a nick in the outer edge, and two small tears.
    if (z <= 19 && ((x >= 31 && x <= 33 && z === 17) ||
                    (x >= 36 && x <= 38 && z === 18))) continue;
    if (x > right - 2 && z >= 23 && z <= 25) continue;
    if ((x === 33 && z === 26) || (x === 34 && z === 26) ||
        (x === 37 && z === 22)) continue;

    const y = 19 + Math.round(1.2 * Math.sin((x - 26) / 5) +
                              0.5 * Math.sin(z / 3));
    const color = z > 28 ? "#fff9e8" :
                  z < 21 ? "#dfd5b9" :
                  (x + z) % 7 === 0 ? "#e7dec7" : "#f5efd9";
    set(x, y, z, color);
    if (x > 27 && x < right - 1) set(x, y - 1, z, color);
  }
}

// Visible stitched reinforcement and a soft cloth seam.
line(27, 18, 33, 36, 19, 30, 0, "#d5cbb1");
line(27, 19, 18, 38, 19, 19, 0, "#cbbd9e");
for (const [x, z] of [[29, 32], [32, 30], [35, 29], [29, 19], [33, 19]]) {
  set(x, 17, z, "#b7a98d");
}

animate("sail", { type: "swing", axis: "z", speed: 2, amplitude: 0.2 });