fractalkitty looking for math? fractalkitty.com

all

Half-Square Hilbert

#random#color#interactive#animation#dom#tool#geometry#truchet#home

cArraycolorPicker1colorPicker2patternSelectrerollButtonblockFunctioncreateControlscontrolsDivbuttonsDivsaveImageButtoncreateNewPatternvalidhasC1hasC2useC1updateColorspickedColor1pickedColor2oldC1oldC2currentArraytruchetblock1block2

let w;
let cnv;
let c1 = [50, 50, 205];
let c2 = [250, 250, 220];
let cArray = [];
let colorPicker1;
let colorPicker2;
let patternSelect;
let rerollButton;

function setup() {
  w = 0.9 * min(windowWidth - 40, windowHeight - 200);
  cnv = createCanvas(w, w);
  cnv.parent("sketch-container");
  noStroke();
  createControls();
  createNewPattern();
  describe(
    "a quilt following a hilbert-like pattern made with half-square triangles."
  );
  loop();
}

function draw() {
  translate(w / 2, w / 2);
  background(c1);
  strokeWeight(w / 200);
  noStroke();
  const blockFunction = window["block" + patternSelect.value()];
  if (typeof blockFunction === "function") {
    blockFunction(w);
  }
}

function windowResized() {
  w = min(windowWidth - 40, windowHeight - 200);
  resizeCanvas(w, w);
  loop();
  redraw();
}

function createControls() {
  const controlsDiv = createDiv();
  controlsDiv.id("controls");
  controlsDiv.style("margin-top", "20px");
  controlsDiv.style("display", "flex");
  controlsDiv.style("flex-wrap", "wrap");
  controlsDiv.style("gap", "20px");

  createP("Background Color:").parent(controlsDiv);

  colorPicker1 = createColorPicker(color(c1[0], c1[1], c1[2]));
  colorPicker1.parent(controlsDiv);
  colorPicker1.input(() => {
    updateColors();
    loop();
  });

  createP("Accent Color:").parent(controlsDiv);
  colorPicker2 = createColorPicker(color(c2[0], c2[1], c2[2]));
  colorPicker2.parent(controlsDiv);
  colorPicker2.input(() => {
    updateColors();
    loop();
  });
  colorPicker1.style("width", "60px");
  colorPicker1.style("height", "30px");
  colorPicker2.style("width", "60px");
  colorPicker2.style("height", "30px");

  createP("Pattern Size:").parent(controlsDiv);
  patternSelect = createSelect();
  patternSelect.parent(controlsDiv);
  for (let i = 1; i <= 7; i++) {
    patternSelect.option(i);
  }
  patternSelect.selected("5");
  patternSelect.changed(() => {
    loop();
    redraw();
  });

  const buttonsDiv = createDiv();
  buttonsDiv.parent(controlsDiv);

  rerollButton = createButton("Reroll Pattern");
  rerollButton.parent(buttonsDiv);
  rerollButton.mousePressed(() => {
    createNewPattern();
    loop();
  });

  const saveImageButton = createButton("Save as Image");
  saveImageButton.parent(buttonsDiv);
  saveImageButton.mousePressed(() => {
    saveCanvas(cnv, "truchet_pattern", "png");
  });
}

function createNewPattern() {
  let valid = false;

  while (!valid) {
    cArray = [];
    let hasC1 = false;
    let hasC2 = false;

    for (let i = 0; i < 8; i++) {
      const useC1 = random() > 0.5;
      cArray[i] = useC1 ? [...c1] : [...c2];

      if (useC1) hasC1 = true;
      else hasC2 = true;
    }

    valid = hasC1 && hasC2;
  }

  loop();
  redraw();
}

function updateColors() {
  const pickedColor1 = colorPicker1.color();
  const pickedColor2 = colorPicker2.color();

  const oldC1 = [...c1];
  const oldC2 = [...c2];

  c1 = [red(pickedColor1), green(pickedColor1), blue(pickedColor1)];
  c2 = [red(pickedColor2), green(pickedColor2), blue(pickedColor2)];

  for (let i = 0; i < cArray.length; i++) {
    const currentArray = cArray[i];

    if (
      Array.isArray(currentArray) &&
      currentArray.length === 3 &&
      currentArray[0] === oldC1[0] &&
      currentArray[1] === oldC1[1] &&
      currentArray[2] === oldC1[2]
    ) {
      cArray[i] = [...c1];
    } else {
      cArray[i] = [...c2];
    }
  }

  loop();
  redraw();
}

function truchet(d1, a, b) {
  push();
  fill(a);
  triangle(-d1, -d1, -d1, d1, d1, d1);
  fill(b);
  triangle(-d1, -d1, d1, -d1, d1, d1);
  pop();
}

function block1(d) {
  push();
  translate(-d / 4, -d / 4);
  truchet(d / 4, cArray[0], cArray[1]);
  translate(0, d / 2);
  truchet(d / 4, cArray[2], cArray[3]);
  pop();
  push();
  translate(d / 4, d / 4);
  truchet(d / 4, cArray[4], cArray[5]);
  translate(0, -d / 2);
  truchet(d / 4, cArray[6], cArray[7]);
  pop();
}

function block2(d) {
  push();
  scale(1 / 2, 1 / 2);
  push();
  translate(-w / 2, -w / 2);
  block1(d);
  translate(w, 0);
  scale(-1, 1);
  block1(d);
  pop();
  push();
  translate(-w / 2, w / 2);
  rotate(PI / 2);
  block1(d);
  pop();
  push();
  translate(w / 2, w / 2);
  rotate(-PI / 2);
  scale(-1, 1);
  block1(d);
  pop();

  pop();
}

function block3(d) {
  push();
  scale(1 / 2, 1 / 2);
  push();
  translate(-w / 2, -w / 2);
  block2(d);
  translate(w, 0);
  scale(-1, 1);
  block2(d);
  pop();
  push();
  translate(-w / 2, w / 2);
  rotate(PI / 2);
  block2(d);
  pop();
  push();
  translate(w / 2, w / 2);
  rotate(-PI / 2);
  scale(-1, 1);
  block2(d);
  pop();

  pop();
}

function block4(d) {
  push();
  scale(1 / 2, 1 / 2);
  push();
  translate(-w / 2, -w / 2);
  block3(d);
  translate(w, 0);
  scale(-1, 1);
  block3(d);
  pop();
  push();
  translate(-w / 2, w / 2);
  rotate(PI / 2);
  block3(d);
  pop();
  push();
  translate(w / 2, w / 2);
  rotate(-PI / 2);
  scale(-1, 1);
  block3(d);
  pop();

  pop();
}

function block5(d) {
  push();
  scale(1 / 2, 1 / 2);
  push();
  translate(-w / 2, -w / 2);
  block4(d);
  translate(w, 0);
  scale(-1, 1);
  block4(d);
  pop();
  push();
  translate(-w / 2, w / 2);
  rotate(PI / 2);
  block4(d);
  pop();
  push();
  translate(w / 2, w / 2);
  rotate(-PI / 2);
  scale(-1, 1);
  block4(d);
  pop();

  pop();
}

function block6(d) {
  push();
  scale(1 / 2, 1 / 2);
  push();
  translate(-w / 2, -w / 2);
  block5(d);
  translate(w, 0);
  scale(-1, 1);
  block5(d);
  pop();
  push();
  translate(-w / 2, w / 2);
  rotate(PI / 2);
  block5(d);
  pop();
  push();
  translate(w / 2, w / 2);
  rotate(-PI / 2);
  scale(-1, 1);
  block5(d);
  pop();

  pop();
}

function block7(d) {
  push();
  scale(1 / 2, 1 / 2);
  push();
  translate(-w / 2, -w / 2);
  block6(d);
  translate(w, 0);
  scale(-1, 1);
  block6(d);
  pop();
  push();
  translate(-w / 2, w / 2);
  rotate(PI / 2);
  block6(d);
  pop();
  push();
  translate(w / 2, w / 2);
  rotate(-PI / 2);
  scale(-1, 1);
  block6(d);
  pop();

  pop();
}