fractalkitty looking for math? fractalkitty.com

Mathober 2025

Chord

#random#trig#classes#grid#sound#interactive#animation#math#geometry#polar#music#mathober

Collab for Mathober

framesmuseelementswavesplayBoolspectrumlisa1lisa2barCounttouchDebounceprevBarsoundProcessPulsemakeGrid

let t = 0;
let frames = 22;
let muse;
let elements = [];
let waves = [];
let playBool = false;
let n = 32;
let spectrum = [];
let lisa1 = 3;
let lisa2 = 5;
let barCount = 0;
let touchDebounce = 0;

function preload() {
  muse = loadSound(
    "/assets/108_fifths_10_04_export-1.m4a"
  );
}

function setup() {
  userStartAudio();
  createCanvas(500, 500);
  background(255);
  frameRate(60);
  lisa1 = random([-2, 2, 3, 5, 8, 12]);
  lisa2 = random([-2, 2, 3, 5, 8, 12]);
  describe("");
  fft = new p5.FFT();
  spectrum = fft.analyze();
  waves = fft.waveform();
  for (let i = 0; i < spectrum.length; i++) {
    elements.push(new Pulse(i, (width / 25) * 10));
  }
  noFill();
  describe(
    "music plays while rose curves of various leafs change with the beat and frequencies. The sketch is on radial graph paper with a staticky feel."
  );
  rectMode(CENTER);
}

function draw() {
  background(245, 250, 255, 2);
  translate(width / 2, height / 2);
  let prevBar = Math.floor((frames - 1) / (133 + 1 / 3));
  barCount = Math.floor(frames / (133 + 1 / 3));
  boolCheck = prevBar === barCount;
  if (!boolCheck && playBool) {
    lisa1 = random([-5, -2, 1, 2, 3, 5, 8, 12, 16, 24]);
    lisa2 = random([-5, -2, 1, 2, 3, 5, 8, 12, 16, 24]);
  }
  if (playBool) {
    t += 0.001;
    frames++;
    if (!muse.isPlaying()) {
      muse.play();
    }
  } else {
    muse.pause();
  }
  soundProcess();

  makeGrid();
  for (let i = 0; i < elements.length; i++) {
    elements[i].reveal();
  }
  noFill();
  strokeWeight(1);
  stroke(100, 110, 120, 10);
  rect(0, 0, width / 1.02, width / 1.02);
  rect(0, 0, width / 1.04, width / 1.04);

  if (!playBool) {
    push();
    fill(50, 60, 70);
    triangle(-20, -20, -20, 20, 20, 0);
    pop();
  }
}

function soundProcess() {
  spectrum = fft.analyze();
  waves = fft.waveform();
  for (let i = 0; i < spectrum.length; i += 1) {
    for (let j = 0; j < 7; j++) {
      push();
      noStroke();
      rotate((j * 360) / 7);
      elements[i].bringToRealization(
        12 * cos(spectrum[i] / lisa1 - i),
        waves[i] * 100
      );
      pop();
    }
  }
}

class Pulse {
  constructor(theta, r) {
    this.theta = theta;
    this.r = r;
    this.d = 0.1;
    this.s = 1;
  }
  reveal() {
    let f = 50 * abs(cos(this.d + this.r));
    stroke(75 + f, 85 + f, 95 + f, 20);
    fill(75 + f, 85 + f, 95 + f, 20);
    circle(
      this.s * this.r * cos(t + this.theta / lisa1),
      this.s * this.r * sin(t + this.theta / lisa1),
      this.d + min(100, 20 * abs(tan(this.s)))
    );
  }
  bringToRealization(a, b) {
    this.s = a / 15 + cos(b / 10) / lisa1;
    this.d = b / lisa2;
  }
}

function makeGrid() {
  d = width / n;
  stroke(100, 110, 120, 10);
  for (let i = 0; i < n; i++) {
    push();
    rotate(((2 * PI) / n) * i);
    strokeWeight(0.5);
    line(-width / 1.5, 0, width / 1.5, 0);
    circle(0, 0, (width / n) * 2 * i);
    pop();

    for (let i = 0; i < 100; i++) {
      push();
      strokeWeight(1);
      stroke(245, 250, 255, 20);
      fill(245, 250, 255, 20);
      x = random(-width / 2, width / 2);
      y = random(-width / 2, width / 2);
      circle(x, y, 2);
      pop();
    }
  }
}

function mousePressed() {
  if (getAudioContext().state !== "running") {
    getAudioContext().resume();
  }
  playBool = !playBool;
  background(255);
  return false;
}

function touchStarted() {
  playBool = !playBool;
  background(255);
  return false;
}

function keyPressed() {
  lisa1 = random([2, 3, 5, 8, 12]);
  lisa2 = random([2, 3, 5, 8, 12]);
}