xxxxxxxxxx
200
let bob;
let anchor;
let velocity;
let restLength = 200;
let k = 0.1;
var damping = 0.90;
var springs = [];
let mic;
let fft;
let bins = 16;
let c1, c2;
var seeds = []
var seeds1 = []
var pointsNum = 20;
var lilFishNum = 12;
let targetAngle = 0.0;
let currentAngle = 0.0;
let globalx = 0.0;
let globaly = 0.0;
let smoothSpeed = 0.05;
let scl = 25.0;
const count = 3;
function setup() {
createCanvas(800, 800);
mic = new p5.AudioIn();
mic.start();
// # of bins
fft = new p5.FFT(0.6, bins);
fft.setInput(mic);
for (i = 0; i < 480; i += 30) {
bob = createVector(20, 60 + i);
anchor = createVector(60, 60 + i);
if (i < 100 && i > 0) {
restLength = restLength * 1.15;
}
restLength = restLength * 0.9;
newSpring = new Spring(anchor, bob, restLength, i);
springs.push(newSpring);
}
frameRate(30);
pixelDensity(1);
createLoop({
duration: 30, //how do make infinate
});
animLoop.noiseFrequency(0.45);
for (var i = 0; i < pointsNum; i++) {
seeds.push([random(0, 100), random(0, 100)]);
}
for (var i = 0; i < lilFishNum; i++) {
seeds1.push([random(0, 100), random(0, 100)]);
}
}
function draw() {
c1 = color(13, 24, 41);
c2 = color(0);
for (let y = 0; y < height; y++) {
n = map(y, 0, height, 0, 1);
let newc = lerpColor(c1, c2, n);
stroke(newc);
line(0, y, width, y);
}
strokeWeight(4);
stroke(255);
for (var i = 0; i < pointsNum; i++) {
var seedOne = seeds[i][0];
var seedTwo = seeds[i][1]
var x = map(animLoop.noise1D(seedOne), -1, 1, -50, width + 50);
var y = map(animLoop.noise1D(seedTwo), -1, 1, -10, height + 50);
push();
noStroke();
fill(250, 250, 250, random(30, 40));
circle(x, y, 5);
pop();
}
for (var i = 0; i < lilFishNum; i++) {
var seedOne = seeds1[i][0];
var seedTwo = seeds1[i][1]
var x = map(animLoop.noise1D(seedOne), -1, 1, -50, width + 50);
var y = map(animLoop.noise1D(seedTwo), -1, 1, -10, height + 50);
push();
noStroke();
fill(220, 100, 150, random(30, 40));
ellipse(x, y, 10, 20);
pop();
}
let spectrum = fft.analyze();
var howMuchFrqForce = 0.4;
globalx = lerp(globalx, mouseX, smoothSpeed);
globaly = lerp(globaly, mouseY, smoothSpeed);
targetAngle = atan2(mouseY - globaly, mouseX - globalx);
currentAngle = lerpAngle(currentAngle, targetAngle, smoothSpeed);
const theta = currentAngle;
translate(globalx, globaly)
rotate(theta);
rotate(PI / 2);
scale(0.4);
for (i = 0; i < springs.length; i++) {
let force = createVector(howMuchFrqForce * spectrum[i] / 2, 0);
springs[i].doPhysics(force);
push();
var sinusoid = 10 * sin(millis() / 200.0 + map(i, 0, springs.length, 0, TWO_PI * 2.5));
translate(sinusoid, -20);
springs[i].drawSpring();
pop();
}
}
class Spring {
constructor(anchor, bob, restLength, i, fishWidth) {
this.velocity = createVector(0, 0);
this.anchor = anchor;
this.bob = bob;
this.restLength = restLength;
this.i = i;
this.fishWidth = fishWidth;
}
drawSpring() {
// var nVertebra = 16;
// var widthAtY = this.fishWidth * sin( map(this.i,0,nVertebra-1, PI*0.1,PI*0.9));
fill(250, 190, 180, 200);
stroke(250, 190, 180, 200);
line(this.anchor.x, this.anchor.y, this.bob.x, this.bob.y);
line(this.anchor.x, this.anchor.y, width / 6 - this.bob.x, this.bob.y);
fill(170, 250, 250, 230);
stroke(170, 250, 250, 200);
circle(this.anchor.x, this.anchor.y, 32);
if (this.i == 0) {
for (var a = 100; a > 0; a -= 10) {
noStroke();
fill(250, 250, 250, a);
let x = 200;
let y = 200;
let r = map(a, 100, 0, 1, 600)
circle(this.anchor.x, this.anchor.y, r);
}
}
fill(150, 250, 250, 200);
stroke(150, 250, 250, 200);
circle(this.bob.x, this.bob.y, 20);
circle(width / 6 - this.bob.x, this.bob.y, 20);
}
doPhysics(frequencyForce) {
let force1 = p5.Vector.sub(this.bob, this.anchor);
let force = p5.Vector.add(force1, frequencyForce);
let x = force.mag() - this.restLength;
force.normalize();
force.mult(-1 * k * x);
// F = A
this.velocity.add(force);
this.bob.add(this.velocity);
this.velocity.mult(damping);
}
}
//thanks to https://editor.p5js.org/lliu29/sketches/NeGyR6QJ/
// Linear interpolation of an angle.
function lerpAngle(a, b, step) {
// Prefer shortest distance,
const delta = b - a;
if (delta == 0.0) {
return a;
} else if (delta < -PI) {
b += TWO_PI;
} else if (delta > PI) {
a += TWO_PI;
}
return (1.0 - step) * a + step * b;
}