/*
CS00a Lecture 7 Demo
Tandem arrays used to model a disease outbreak
- Read through the program for comprehension
- Change Global Variables to edit the model
- change parameters in socialDistance() to effect how elements interact
*/
int n = 20; // number of elements in the model
float[] x = new float[n];
float[] y = new float[n];
float[] vx = new float[n];
float[] vy = new float[n];
boolean[] infected = new boolean[n];
int[] framesInfected = new int[n];
int LENINFECT = 50; // how many frames does one stay infected?
int DIAMETER_INFECT = 20; // how close do two need to be for transmission?
int MAXSPEED = 5;
float ACCEL = 0.2;
void setup() {
size(500, 500);
frameRate(5);
for(int i = 0; i < n; i++) {
x[i] = random(width);
y[i] = random(height);
vx[i] = random(-MAXSPEED,MAXSPEED);
vy[i] = random(-MAXSPEED,MAXSPEED);
if(random(100) < 20) infected[i] = true;
framesInfected[i] = 0;
}
println(PFont.list());
textFont(createFont("monospace", 40));
}
void draw() {
background(255);
int numInfectious = 0, numRemoved = 0, numSusceptible = 0;
for(int i = 0; i < n; i++) {
move(i);
// socialDistance(i);
infect(i);
if (!infected[i]) {
fill(0, 255, 0);
numSusceptible++;
} else if(framesInfected[i] < LENINFECT) {
fill(255, 0, 0);
framesInfected[i]++;
numInfectious++;
} else {
numRemoved++;
fill(100);
}
noStroke();
ellipse(x[i],y[i],8,8);
noFill();
stroke(100,50);
ellipse(x[i],y[i],DIAMETER_INFECT,DIAMETER_INFECT);
}
textSize(20);
fill(0);
text("Infectious: "+numInfectious,50,100);
text("Removed: "+numRemoved,50,120);
text("Susceptible: "+numSusceptible,50,140);
}
// move each element, keeping them all within the canvas
void move(int i) {
x[i] += vx[i];
y[i] += vy[i];
vx[i] += random(-ACCEL,ACCEL);
vx[i] = constrain(vx[i],-MAXSPEED,MAXSPEED);
vy[i] += random(-ACCEL,ACCEL);
vy[i] = constrain(vy[i],-MAXSPEED,MAXSPEED);
if(x[i] < 0) x[i] += width;
if(x[i] > width) x[i] -= width;
if(y[i] < 0) y[i] += height;
if(y[i] > height) y[i] -= height;
}
// how much does each entity distance from the others?
// what happens when REPEL is a negative number?
void socialDistance(int i) {
int DIST = 50;
float REPEL = .01;
for(int j=0; j<n; j++) {
// check dist
if(dist(x[i], y[i], x[j], y[j]) < DIST) {
// move away!
vx[i] += (x[i] - x[j]) * REPEL;
vy[i] += (y[i] - y[j]) * REPEL;
}
}
}
// check if this index is infected, and if it's close enough to infect others
void infect(int i) {
// check for infection
if(infected[i] && framesInfected[i] < LENINFECT && framesInfected[i] > 0) {
for(int j = 0; j < n; j++) {
// is anyone else close enough to get infected?
if(i != j && !infected[j] && dist(x[i],y[i],x[j],y[j]) < DIAMETER_INFECT) {
infected[j] = true;
framesInfected[j] = 0; // wait one frame before they can infect others
stroke(0,0,255);
ellipse(x[i],y[i],DIAMETER_INFECT,DIAMETER_INFECT);
stroke(255,0,0);
ellipse(x[j],y[j],DIAMETER_INFECT,DIAMETER_INFECT);
}
}
}
}