Else if not triggering with boolean's

Hello!
After watching the coding train for a while I decided to download processing and start learning how to create my own programs. I started last week.
Currently I am working on a infection simulation. I am trying to get my “person” class to recognize when it’s been infected then have a waiting period where it then becomes recovered. To do this I have two boolean variables that are both false at the start. I then check the position of a “person” against every other person and if they touch and the other is infected then they become infected=true. Now I would like to have a “timer” start for them to recover. The not infecting other people is working I do believe however, they are not changing their color. I will post the full code below. The main parts that pertain to this are probably the infected and recover functions in the person class.

Any help is greatly appreciated!
Thanks


int population = 100;
person[] People = new person[population];

void setup() {
  size(1200, 600);

  for (int i = 0; i < population; i++) {
    People[i] = new person(i, People);
  }
}
void draw() {
  background(0);
  for (person p : People) {
    p.move();
    p.display();
    p.initialize();
    p.infected(People);
    p.recover();
  }
}

class person {

  PVector velocity = new PVector(random(-1, 1), random(-1, 1));
  int size = 10;
  int bsize = 100;
  float x1 = random(0+bsize/2, (width/2)-bsize/2);
  float y1 = random(0+bsize/2, height-bsize/2);
  float x2 = random(x1-bsize/3, x1+bsize/3);
  float y2 = random(y1-bsize/3, y1+bsize/3);
  boolean infected;
  boolean recovered = false;
  person[] others;
  int num;
  float time;

  person(int nin, person[] oin) {
    others = oin;
    num = nin;
  }

  void initialize() {
    if (num < 2) {
      infected = true;
    }
  }

  void barrier() {
    noFill();
    stroke(255, 0, 0);
    circle(x1, y1, bsize);
  }

  void display() {
    if (infected) {
      stroke(255, 0, 0);
      fill(255, 0, 0);
      ellipse(x2, y2, 10, 10);
    } else if (recovered) {
      stroke(220, 220, 220);
      fill(220, 220, 220);
      ellipse(x2, y2, 10, 10);
    } else {
      stroke(255);
      fill(255);
      ellipse(x2, y2, 10, 10);
    }
  }

  void move() {
    float distance = dist(x1, y1, x2, y2);
    if (distance > bsize/2) {
      velocity = velocity.mult(-1);
    }
    x2 = x2 + velocity.x;
    y2 = y2 + velocity.y;
  }

  void infected(person[] others) {
    for (person other : others) {
      float d = dist(x2, y2, other.x2, other.y2);
      //println(d);
      if ( d < size && other.infected & !recovered) {
        infected = true;
        time = millis();
      }
    }
  }

  void recover() {
    int wait = 10000;
    if (millis() - time >= wait) {
      infected = false;
      recovered = true;
    }
  }
}
1 Like

there are a couple of things that pop out immediately to me.

  1. you are testing the “Person” against themselves and so they can never recover as they are infecting themselves
  2. if a person is infected they shouldn’t restart their infection (at least I wouldn’t think so)

here’s an example which demonstrates the people being infected and recovering without their infection restarting. it also shows the recovery with the “Person” (ellipse) fading in colour as it recovers. I did make the assumption that you want a person once recovered not be infected again. anyways best of luck with it.

int population;
Person[] people;

void setup() {
 size(1200, 600);

 population = 100;
 people = new Person[population];
 for (int i = 0; i < population; i++) {
   people[i] = new Person(i);
 }
}
void draw() {
 background(0);
 for (int i = 0; i < population; i++) {
   Person p = people[i];
   p.move();
   p.infected(people, i);
   p.recover();
   p.display();
 }
}

class Person {

 PVector velocity = new PVector(random(-1, 1), random(-1, 1));
 int size = 10;
 int bsize = 100;
 float x1 = random(0+bsize/2, (width/2)-bsize/2);
 float y1 = random(0+bsize/2, height-bsize/2);
 float x2 = random(x1-bsize/3, x1+bsize/3);
 float y2 = random(y1-bsize/3, y1+bsize/3);
 boolean infected = false;
 boolean recovered = false;
 int time;
 int recoveryTime = 10000;

 Person(int nin) {
   if (nin < 2)
     infected = true;
 }

 void barrier() {
   noFill();
   stroke(255, 0, 0);
   circle(x1, y1, bsize);
 }

 void display() {
   if (infected) {
     stroke(255, 0, 0);
     int shade = (int)map(1.0 - (float)(millis() - time) / recoveryTime, 0, 1, 0, 255);
     fill(shade, 0, 0);
     ellipse(x2, y2, 10, 10);
   } else if (recovered) {
     stroke(220, 220, 220);
     fill(220, 220, 220);
     ellipse(x2, y2, 10, 10);
   } else {
     stroke(255);
     fill(255);
     ellipse(x2, y2, 10, 10);
   }
 }

 void move() {
   float distance = dist(x1, y1, x2, y2);
   if (distance > bsize/2) {
     velocity = velocity.mult(-1);
   }
   x2 = x2 + velocity.x;
   y2 = y2 + velocity.y;
 }

 void infected(Person[] others, int skipIndex) {
   if(infected) return;
   for (int i = 0; i < others.length; i++) {
     if (i != skipIndex) {
       Person other = others[i];
       float d = dist(x2, y2, other.x2, other.y2);
       //println(d);
       if ( d < size && other.infected && !recovered) {
         infected = true;
         time = millis();
       }
     }
   }
 }

 void recover() {
   if (infected) {
     if (millis() - time >= recoveryTime) {
       infected = false;
       recovered = true;
     }
   }
 }
}
2 Likes

Ahh okay I see what you did there!
Thanks! It works exactly as I intended.
Now I’ll try to graph the number of infected, recovered, and susceptible vs time.

1 Like