xxxxxxxxxx
81
// Idea from this article:
// https://cargocollective.com/sagejenson/physarum
const positions = [];
const headings = [];
const numParts = 1000;
const senseAng = 3.14/16;
const senseRad = 2;
const moveAng = 3.14/32;
const moveRad = 0.1;
const decay = 0.99;
function setup() {
createCanvas(200, 200);
for(let i = 0; i < numParts; i ++) {
positions.push(createVector(random(width), random(height)));
headings.push(random(TWO_PI));
}
stroke(255);
background(0);
}
function draw() {
// Sense, Rotate, Move
for(let i = 0; i < numParts; i ++) {
headings[i] = getHeading(positions[i], headings[i]);
positions[i].x += cos(headings[i]) * moveRad;
positions[i].y += sin(headings[i]) * moveRad;
positions[i].x %= width;
positions[i].y %= height;
}
// Deposite
for(let i = 0; i < numParts; i ++) {
const p = positions[i];
point(p.x, p.y);
}
// // Defuse
// filter(BLUR);
// Decay
blendMode(MULTIPLY);
background(255 * decay);
blendMode(BLEND);
}
function getHeading(pos, heading) {
const fSensePos = getSensorPos(pos, heading);
const lSensePos = getSensorPos(pos, heading - senseAng);
const rSensePos = getSensorPos(pos, heading + senseAng);
const f = get(fSensePos.x, fSensePos.y);
const l = get(lSensePos.x, lSensePos.y);
const r = get(rSensePos.x, rSensePos.y);
if(f > l && f > r) {
return heading; // forward is largest, no change
} else if(f < l && f < r) {
return heading + (random(1) < 0.5 ? moveAng : -moveAng); // forward smallest, random turn
} else if(l < r) {
return heading + moveAng; // right largest, left smallest, turn right
} else if(r < l) {
return heading - moveAng; // left largest, right smallest, turn left
}
return heading;
}
function getSensorPos(pos, angle) {
const vec = pos.copy();
vec.x += cos(angle) * senseRad;
vec.y += sin(angle) * senseRad;
return vec;
}