as part of math monday, patrick, sam & i worked on penrose tilings.
followed this: https://preshing.com/20110831/penrose-tiling-explained/; wrote this:
//penrose:
let all_tris = [];
function setup() {
createCanvas(1000, 1000);
//draw first one:
all_tris[0] = new Triangle(500, 50, 208, 950, 792, 950, 0);
//subdivide:
for (let i = 0; i < 5; i++) {
all_tris = all_tris.map((t) => t.subdivide()).flat();
}
}
function draw() {
background(255);
for (let tri of all_tris) {
tri.display();
}
}
class Triangle {
constructor(x1, y1, x2, y2, x3, y3, col) {
this.x1 = x1;
this.x2 = x2;
this.x3 = x3;
this.y1 = y1;
this.y2 = y2;
this.y3 = y3;
this.col = col;
}
display() {
if (this.col == 0) {
fill(255, 0, 0);
} else {
fill(0, 0, 255);
}
noStroke();
triangle(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3);
// this.subdivide();
}
subdivide() {
//px = b / a+b * ax, and a / a + b * bx -> to find how far along you are on line ab.
if (this.col == 0) {
//red:
let n = random();
let [px, py] = [0, 0];
if (n < 0.5) {
[px, py] = find_p(this.x1, this.y1, this.x2, this.y2);
return [
new Triangle(this.x3, this.y3, px, py, this.x2, this.y2, 0),
new Triangle(px, py, this.x1, this.y1, this.x3, this.y3, 1),
];
} else {
[px, py] = find_p(this.x1, this.y1, this.x3, this.y3);
return [
new Triangle(this.x2, this.y2, px, py, this.x3, this.y3, 0),
new Triangle(px, py, this.x1, this.y1, this.x2, this.y2, 1),
];
}
} else {
//blue:
let n = random();
if (n < 0.5) {
let [qx, qy] = find_p(this.x2, this.y2, this.x1, this.y1);
let [rx, ry] = find_p(this.x2, this.y2, this.x3, this.y3);
return [
new Triangle(qx, qy, this.x2, this.y2, rx, ry, 1),
new Triangle(rx, ry, this.x1, this.y1, qx, qy, 0),
new Triangle(rx, ry, this.x1, this.y1, this.x3, this.y3, 1),
];
} else {
let [qx, qy] = find_p(this.x3, this.y3, this.x1, this.y1);
let [rx, ry] = find_p(this.x3, this.y3, this.x2, this.y2);
return [
new Triangle(qx, qy, this.x3, this.y3, rx, ry, 1),
new Triangle(rx, ry, this.x1, this.y1, qx, qy, 0),
new Triangle(rx, ry, this.x1, this.y1, this.x2, this.y2, 1),
];
}
}
}
}
function find_p(ax, ay, bx, by) {
let a_frac = (Math.sqrt(5) - 1) / 2;
let b_frac = 1 - a_frac;
let px = b_frac * ax + a_frac * bx;
let py = b_frac * ay + a_frac * by;
return [px, py];
}
patrick & sam were kind enough to let me program.
afterwards, i made a program that does this:

//square subdivision.
//given a set of starting coordinates, draw yourself over & over again with shrinking widths & alternating colours; until you reach an end point.
let sw = false;
function setup() {
createCanvas(1000, 1000);
rectMode(CENTER, CENTER);
background(255);
}
function draw() {
draw_sq2(width / 2, height / 2, 700, 0);
noLoop();
}
function draw_sq2(x, y, w, a, c_switch = true) {
if (w < 1) return;
let p1 = createVector(-w / 2, -w / 2);
let p2 = createVector(w / 2, -w / 2);
let p3 = createVector(w / 2, w / 2);
let p4 = createVector(-w / 2, w / 2);
let mult = 10;
p1.add(random() * mult);
p2.add(random() * mult);
p3.add(random() * mult);
p4.add(random() * mult);
fill(c_switch ? 255 : 0);
noStroke();
push();
translate(x, y);
rotate(a);
beginShape();
vertex(p1.x, p1.y);
vertex(p2.x, p2.y);
vertex(p3.x, p3.y);
vertex(p4.x, p4.y);
endShape(CLOSE);
pop();
a += 0.015;
draw_sq2(x, y, w - 5, a, !c_switch);
}
function mousePressed(){
save ("frame.webp");
}
same idea as the penrose tiling, recursively draw a square.