// Truchet Tiles
//
// A grid of randomly-rotated tiles. Three tile types:
// "Quarter Arcs" — the classic Truchet: two opposite quarter-circle arcs
// "Diagonal Lines" — a diagonal line, 10PRINT style
// "Triangles" — filled triangle in one corner (Smith variant)
//
// Random seed is fixed from p.randomSeed() on setup so each build is stable.
export const PARAMS = {
cellSize: { value: 60, min: 20, max: 200, step: 5, label: "Cell Size", folder: "Structure", rebuildOnChange: true },
pattern: { value: "Quarter Arcs", options: ["Quarter Arcs", "Diagonal Lines", "Triangles"], label: "Tile Type", folder: "Structure" },
fg: { value: "#e8d8a8", type: "color", label: "Lines", folder: "Appearance" },
bg: { value: "#1c1c1c", type: "color", label: "Background", folder: "Appearance" },
strokeW: { value: 5, min: 1, max: 24, step: 0.5, label: "Stroke Width", folder: "Appearance" },
};
export function sketchSetup(p, w, h) {
p.randomSeed(42);
return {};
}
export function sketchDraw(p, w, h, params) {
// Re-seed every draw for deterministic results
p.randomSeed(42);
const cs = params.cellSize;
const cols = Math.ceil(w / cs) + 1;
const rows = Math.ceil(h / cs) + 1;
p.background(params.bg);
p.stroke(params.fg);
p.strokeWeight(params.strokeW);
p.noFill();
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const rot = Math.floor(p.random(4)); // 0..3 rotations of 90°
const x = col * cs;
const y = row * cs;
p.push();
p.translate(x + cs / 2, y + cs / 2);
p.rotate((p.HALF_PI) * rot);
if (params.pattern === "Quarter Arcs") {
// Two quarter-circle arcs from opposite corners
// Arc from bottom-left corner (rotated frame: -cs/2, cs/2)
p.arc(-cs / 2, cs / 2, cs, cs, -p.HALF_PI, 0);
// Arc from top-right corner
p.arc(cs / 2, -cs / 2, cs, cs, p.PI, p.PI + p.HALF_PI);
} else if (params.pattern === "Diagonal Lines") {
// Single diagonal line corner to corner
p.line(-cs / 2, -cs / 2, cs / 2, cs / 2);
} else {
// Triangles: filled triangle in bottom-left corner (Smith variant)
p.fill(params.fg);
p.triangle(-cs / 2, -cs / 2, cs / 2, -cs / 2, -cs / 2, cs / 2);
p.noFill();
}
p.pop();
}
}
}