# Trigger animation effect after object collision

**URL:** <https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811>\
**Category:** Coding Questions\
**Created:** [March 19, 2020, 6:47pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811 "2020-03-19T18:47:49Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 19, 2020, 6:47pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/1 "2020-03-19T18:47:49Z")

</div>

I want to create a “pulse” effect after objects collide with each other. The intended effect in this example is that when the particles collide (come within a certain distance from each other) an ellipse appears, grows to a specified radius, then disappears. The ellipse x, y coordinates will be the same as the particle’s (ellipse moves with the particle). And this animation should occur as a trigger - once triggered, the distance between particles should no longer matter.

In the code below the effect is not what I’m intending. Instead of the particle continuing it’s trajectory at the same velocity with an ellipse growing from the center, the particle slows down, an ellipse appears for the time that the two particles are near each other, then disappears.

Here’s a sample:

````auto
ArrayList<Particle> particles;

void setup() {
  size(400, 400);
  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    float initX = random(0, width);
    float initY = random(0, height);
    Particle particle = new Particle(initX, initY);
    particles.add(particle);
  }
}

void draw() {
  background(0);
  // There's a much cleaner way to do this, but showing this
  // way to illustrate the example.
  Particle particle1 = particles.get(0);
  Particle particle2 = particles.get(1);
  
  // Make the particles seek each other
  particle1.seek(particle2.pos);
  particle2.seek(particle1.pos);
  
  // Update position and display
  particle1.update();
  particle1.display();
  
  particle2.update();
  particle2.display();
  
  // NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles,25); 
  }
}

class Particle {
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r;
  boolean interacting;
  
  Particle(float x, float y) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 4.0;
    maxforce = 0.03;
    r = 15;
    interacting = false;
  }
  
  void applyForce(PVector force) {
    acceleration.add(force); 
  }
  
  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
  
  // NEED HELP HERE:
  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.
  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, float radius) {
    for (Particle other : particles) {
      float iradius = 0.0;
      float d = PVector.dist(pos, other.pos);
      
      // trigger the interaction.
      if ((d > 0) && (d <= radius)) {
        interacting = true;
      }
      
      // NEED HELP HERE.
      // what to do while interacting.
      while (interacting) {
        if (iradius < radius) {
          pushMatrix();
            noFill();
            stroke(255, 255, 0);
            ellipse(pos.x, pos.y, iradius, iradius);
          popMatrix();
          iradius += 0.01;           
        } else {
          interacting = false;
        }
      }
    }
   } // end interact function.
  
  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }
  
  void display() {
    fill(255);
    ellipse(pos.x, pos.y, r, r);
  }
  
} // end Particle```
````

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 19, 2020, 8:17pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/2 "2020-03-19T20:17:46Z")

</div>

Hello !

and welcome to this forum! It’s a great community.

Wow, you posted a very good code and formatted correctly… you are way ahead already…

**One remark:**

The way you do it, you compare all particles to all particles (one for loop in draw calling another one in `interact()`). This is technically too often. Instead you could have :

```auto
for loop i1 0 to size-1
    for loop i2+1 to size

```

thus you avoid

- comparing a to b and later b to a.
- comparing also a to a

**Your question :**

It’s good that you have the variable `interacting` and that it stays true once it is true. Because then the pulse can go on even when the particle has moved on (and the distance is bigger again).

but you have a while loop doing the pulse and that’s wrong, because the screen gets updated only once at the end of draw() and not throughout. _(or do you want to draw multiple rings at once?)_

so have this

```auto
if(interacting) {
        if (iradius < radius) {
          pushMatrix();
            noFill();
            stroke(255, 255, 0);
            ellipse(pos.x, pos.y, iradius, iradius);
          popMatrix();
          iradius += 0.01;           
        } else {
          interacting = false;
        }
}

```

but inside of the method `display() ` in the class!

Also you want to store the position of the ellipse in the moment of the collision in an extra variable and display the pulse there, because the ellipses would move on but the pulse should not.

pushMatrix and popMatrix is not necessary with

```auto
        ellipse(x1, y1, 
          iradius, iradius);

```

It’s only necessary if you’d use translate etc.

Chrisir

**My version**

```auto

ArrayList<Particle> particles;

void setup() {
  size(400, 400);
  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    float initX = random(0, width);
    float initY = random(0, height);
    Particle particle = new Particle(initX, initY, i);
    particles.add(particle);
  }
}

void draw() {
  background(0);

  // There's a much cleaner way to do this, but showing this
  // way to illustrate the example.
  Particle particle1 = particles.get(0);
  Particle particle2 = particles.get(1);

  // Make the particles seek each other
  particle1.seek(particle2.pos);
  particle2.seek(particle1.pos);

  // Update position and display
  particle1.update();
  particle1.display();

  particle2.update();
  particle2.display();

  // NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles, 25);
  }
}

// =================================================================

class Particle {
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r;
  boolean interacting;

  int id;

  float iradius = 0.0;
  float radius = 25.0;
  float x1, y1; 

  //constr
  Particle(float x, float y, 
    int i_) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 4.0;
    maxforce = 0.03;
    r = 15;
    interacting = false;

    id=i_;
  } //constr

  void applyForce(PVector force) {
    acceleration.add(force);
  }

  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }

  // NEED HELP HERE:
  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.
  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, 
    float radius) {
    for (Particle other : particles) {

      if (id==other.id) {
        return;
      }

      float d = PVector.dist(pos, other.pos);

      // trigger the interaction.
      if ( d <= radius ) {
        interacting = true;
        iradius = 0.0;
        x1=(pos.x+other.pos.x)/2;
        y1=(pos.y+other.pos.y)/2;
        println("hit");
      }
    }
  } // end interact function.

  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }

  void display() {
    fill(255);
    ellipse(pos.x, pos.y, r, r);

    if (interacting) {
      if (iradius < radius+20) {
        //pushMatrix();
        noFill();
        // fill(255, 255, 0);
        stroke(255, 255, 0);

        ellipse(x1, y1, 
          iradius, iradius);
        //popMatrix();
        iradius += 1.101;
      } else {
        interacting = false;
      }
    }
  }//func
} // end Particle class
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 19, 2020, 9:02pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/3 "2020-03-19T21:02:47Z")

</div>

you can also use a while loop to draw many rings and let it grow

see here

```auto

ArrayList<Particle> particles;

void setup() {
  size(400, 400);
  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    float initX = random(0, width);
    float initY = random(0, height);
    Particle particle = new Particle(initX, initY, i);
    particles.add(particle);
  }
}

void draw() {
  background(0);

  // There's a much cleaner way to do this, but showing this
  // way to illustrate the example.
  Particle particle1 = particles.get(0);
  Particle particle2 = particles.get(1);

  // Make the particles seek each other
  particle1.seek(particle2.pos);
  particle2.seek(particle1.pos);

  // Update position and display
  particle1.update();
  particle1.display();

  particle2.update();
  particle2.display();

  // NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles, 25);
  }
}

// =================================================================

class Particle {
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r;
  boolean interacting;

  int id;

  int iradius = 0;
  float radius = 25.0;
  float x1, y1; 

  int max; 

  //constr
  Particle(float x, float y, 
    int i_) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 4.0;
    maxforce = 0.03;
    r = 15;
    interacting = false;

    id=i_;
  } //constr

  void applyForce(PVector force) {
    acceleration.add(force);
  }

  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }

  // NEED HELP HERE:
  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.
  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, 
    float radius) {
    for (Particle other : particles) {

      // we don't want to compare a against a
      if (id==other.id) {
        return;
      }

      float d = pos.dist(other.pos);

      // trigger the interaction.
      if ( d <= radius ) {
        interacting = true;
        iradius = 5;
        max = 17; 
        x1 = (pos.x+other.pos.x)/2;
        y1 = (pos.y+other.pos.y)/2;
        // println("hit");
      }
    }
  } // end interact function.

  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }

  void display() {
    fill(255);
    ellipse(pos.x, pos.y, r, r);

    if (interacting) {
      iradius=0;
      while (iradius < max) {
        noFill();
        stroke(255, 255, 0);
        ellipse(x1, y1, 
          iradius, iradius);
        iradius += 9;
      }
      max += 1.101;
      if (max > 86) {
        interacting = false;
      }
    }
  }//func
} // end Particle class
//

```

---

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 23, 2020, 2:08pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/4 "2020-03-23T14:08:55Z")

</div>

@Chrisir Thank you. You clarified for me how to get the triggered effect - putting that in `display()` instead of the `interact` function itself. Now, with the code below I’m expecting each particle to display the effect. However, only one does when the particles cross paths.

I would expect that in for each loop of `draw()` this piece of code would run for each particle, and trigger the interaction effect

```auto
// NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles,25); 
  }

```

But instead, the effect only triggers for a single particle. Any idea for why?

```auto
ArrayList<Particle> particles;

void setup() {
  size(400, 400);
  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    float initX = random(0, width);
    float initY = random(0, height);
    Particle particle = new Particle(initX, initY, i);
    particles.add(particle);
  }
}

void draw() {
  background(0);
  // There's a much cleaner way to do this, but showing this
  // way to illustrate the example.
  Particle particle1 = particles.get(0);
  Particle particle2 = particles.get(1);
  
  // Make the particles seek each other
  particle1.seek(particle2.pos);
  particle2.seek(particle1.pos);
  
  // Update position and display
  particle1.update();
  particle1.display();
  
  particle2.update();
  particle2.display();
  
  // NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles,25); 
  }
  
  
  
}

class Particle {
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r;
  boolean interacting;
  
  int id;
  
  float iradius = 0.0;
  float radius = 50.0;
  float x1, y1;
  
  Particle(float x, float y, int id_) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 4.0;
    maxforce = 0.03;
    r = 15;
    interacting = false;
    id = id_;
  } // end Particle constructor
  
  void applyForce(PVector force) {
    acceleration.add(force); 
  }
  
  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }
  
  // NEED HELP HERE:
  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.
  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, float radius) {
    for (Particle other : particles) {
      if (id == other.id) {
        return; 
      }
      float d = PVector.dist(pos, other.pos);
      
      // trigger the interaction.
      if (d <= radius) {
        interacting = true;
        iradius = 0.0;
        x1 = (pos.x + other.pos.x)/2;
        y1 = (pos.y + other.pos.y)/2;
      }
    }
   } // end interact function.
  
  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }
  
  void display() {
    fill(255);
    ellipse(pos.x, pos.y, r, r);
    
    if (interacting) {
      if (iradius < radius) {
        noFill();
        stroke(255, 255, 0);
        ellipse(pos.x, pos.y, iradius, iradius);
        iradius += 0.7;
      } else {
        interacting = false; 
      }
    }
  } // end display function.
  
} // end Particle class.

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 23, 2020, 2:54pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/5 "2020-03-23T14:54:12Z")

</div>

here

I first had it so that the pulse was in the place where the collision occurred (x1,y1) and stayed there.

Now the pulse goes with both circles.

Chrisir

```auto
ArrayList<Particle> particles;

void setup() {
  size(400, 400);

  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    float initX = random(0, width);
    float initY = random(0, height);
    Particle particle = new Particle(initX, initY, i);
    particles.add(particle);
  }
}

void draw() {
  background(0);

  // There's a much cleaner way to do this, but showing this
  // way to illustrate the example.
  Particle particle1 = particles.get(0);
  Particle particle2 = particles.get(1);

  // Make the particles seek each other
  particle1.seek(particle2.pos);
  particle2.seek(particle1.pos);

  // Update position and display
  particle1.update();
  particle1.display();

  particle2.update();
  particle2.display();

  // NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles, 25);
  }
}

// ============================================================

class Particle {
  // 
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r = 15;
  boolean interacting = false;

  int id;

  float iradius = 0.0;
  float radius = 50.0;
  // float x1, y1;

  Particle(float x, float y, 
    int id_) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 4.0;
    maxforce = 0.03;

    id = id_;
  } // end Particle constructor

  void applyForce(PVector force) {
    acceleration.add(force);
  }

  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }

  // NEED HELP HERE:
  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.

  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, float radius) {
    for (Particle other : particles) {
      if (id == other.id) {
        continue; // skip
      }
      float d = PVector.dist(pos, other.pos);

      // trigger the interaction.
      if (d <= radius) {
        interacting = true;
        iradius = r;
        //x1 = (pos.x + other.pos.x)/2;
        //y1 = (pos.y + other.pos.y)/2;
      }
    }
  } // end interact function.

  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }

  void display() {
    fill(255);
    ellipse(pos.x, pos.y, 
      r, r);

    if (interacting) {
      if (iradius < radius+22) {
        noFill();
        stroke(255, 255, 0);
        ellipse(pos.x, pos.y, 
          iradius, iradius);
        iradius += 2.07;
      } else {
        interacting = false;
      }
    }
  } // end display function.
  //
} // end Particle class.
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 23, 2020, 2:55pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/6 "2020-03-23T14:55:09Z")

</div>

> [@codingcomplexity](#):
>
> if (id == other.id) {  
> return;  
> }

this was one big error by me.

It must be

```auto

if (id == other.id) { 
   continue; 
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 23, 2020, 3:03pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/7 "2020-03-23T15:03:29Z")

</div>

new version with different colors

```auto

ArrayList<Particle> particles;

void setup() {
  size(400, 400);

  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    float initX = random(0, width);
    float initY = random(0, height);
    Particle particle = new Particle(initX, initY, i);
    particles.add(particle);
  }
}

void draw() {
  background(0);

  // There's a much cleaner way to do this, but showing this
  // way to illustrate the example.
  Particle particle1 = particles.get(0);
  Particle particle2 = particles.get(1);

  // Make the particles seek each other
  particle1.seek(particle2.pos);
  particle2.seek(particle1.pos);

  // Update position and display
  particle1.update();
  particle1.display();

  particle2.update();
  particle2.display();

  // NEED HELP: Attempt at interaction here.
  for (Particle particle : particles) {
    particle.interact(particles, 25);
  }
}

// ============================================================

class Particle {
  // 
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r = 15;
  boolean interacting = false;
  float pulseSpeed;

  int id;

  float iradius = 0.0;
  float radius = 50.0;
  color colEllipse = color (random(255), 0, random(255)); 

  Particle(float x, float y, 
    int id_) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 4.0;
    maxforce = 0.03;

    id = id_;

    // we can make the pulse of #0 of different speed
    if (id==0) 
      pulseSpeed=0.9;
    else pulseSpeed=0.9;
    //
  } // end Particle constructor

  void applyForce(PVector force) {
    acceleration.add(force);
  }

  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }

  // NEED HELP HERE:
  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.

  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, float radius) {
    for (Particle other : particles) {
      if (id == other.id) {
        continue; // skip
      }
      float d = PVector.dist(pos, other.pos);

      // trigger the interaction.
      if (d <= radius) {
        interacting = true;
        iradius = r+2;
        //x1 = (pos.x + other.pos.x)/2;
        //y1 = (pos.y + other.pos.y)/2;
      }//if
    }//for
  } // end interact function.

  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }

  void display() {
    fill(colEllipse);
    noStroke(); 
    ellipse(pos.x, pos.y, 
      r, r);

    if (interacting) {
      if (iradius < radius) {
        noFill();
        stroke(255, 255, 0);
        ellipse(pos.x, pos.y, 
          iradius, iradius);
        iradius += pulseSpeed;
      } else {
        interacting = false;
      }
    }
  } // end display function.
  //
} // end Particle class.
//

```

**Remark I**

```auto

      if (id == other.id) {
        continue; // skip
      }

```

OR more comprehensible

```auto
  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(ArrayList<Particle> particles, float radius) {

    for (Particle other : particles) {

      if (id != other.id) { // !!!!!!!!!!!!!!!!!!

      float d = PVector.dist(pos, other.pos);

      // trigger the interaction.
      if (d <= radius) {
        interacting = true;
        iradius = r+2;
        //x1 = (pos.x + other.pos.x)/2;
        //y1 = (pos.y + other.pos.y)/2;
      }//if
     }//if
    }//for
  } // end interact function.

```

**Remark II**

as I mentioned compare all against all is time consuming (you compare double)

instead in draw

```auto
for loop i1 0 to size-1
    for loop i2+1 to size

```

and then in interact() set both particles `interacting = true;`

Chrisir

---

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 24, 2020, 4:34pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/8 "2020-03-24T16:34:13Z")

</div>

@Chrisir Thanks for the tips. Help me dig in a bit and understand how to implement this. I love to find efficiency where possible.

> [@Chrisir](#):
>
> **Remark II**
> 
> as I mentioned compare all against all is time consuming (you compare double)
> 
> instead in draw
> 
> ```auto
> for loop i1 0 to size-1
> for loop i2+1 to size
> 
> ```
> 
> and then in interact() set both particles `interacting = true;`

With the change you outlined would I still need to pass the `ArrayList<Particle>` object to the `Particle.interact()` method?

Or would I change this to accept a single instance of `Particle` (and pass each `Particle` object from the `particles` array using a loop in the `draw()` function like you one you posted?

---

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 24, 2020, 5:55pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/9 "2020-03-24T17:55:15Z")

</div>

Here is my implementation of the code suggestions above. Comments, suggestions, tips are welcome.

```auto
ArrayList<Particle> particles;

void setup() {
  size(400, 400);

  particles = new ArrayList<Particle>();
  int numparticles = 2;
  for (int i=0; i < numparticles; i++) {
    int initX = int(random(0, width));
    int initY = int(random(0, height));
    Particle particle = new Particle(initX, initY, i);
    particles.add(particle);
  }
}

void draw() {
  background(0);

  for (int i=0; i<particles.size()-1; i++) {
    for (int j=i+1; j<particles.size(); j++) {
      Particle particle = particles.get(i);
      Particle other = particles.get(j);
      
      // make the particles seek each other
      particle.seek(other.pos);
      other.seek(particle.pos);
      
      // interact with each each other
      particle.interact(other, 2);
      
      // then update physics and display
      particle.update();
      particle.display();
      
      other.update();
      other.display();
    }
  }
}

class Particle {
  // 
  PVector pos;
  PVector velocity;
  PVector acceleration;
  float maxforce;
  float maxspeed;
  float r = 15;
  boolean interacting = false;
  float pulseSpeed;

  int id;

  float iradius = 0.0;
  float radius = 50.0;
  color colEllipse = color (random(255), 0, random(255)); 

  Particle(int x, int y, 
    int id_) {
    acceleration = new PVector(0, 0);
    velocity = new PVector(0, 0);
    pos = new PVector(x, y);
    maxspeed = 2.0;
    maxforce = 0.01;

    id = id_;

    // we can make the pulse of #0 of different speed
    if (id==0) 
      pulseSpeed=0.5;
    else pulseSpeed=0.9;
    //
  } // end Particle constructor

  void applyForce(PVector force) {
    acceleration.add(force);
  }

  void seek(PVector target) {
    PVector desired = PVector.sub(target, pos);
    desired.normalize();
    desired.mult(maxspeed);
    PVector steer = PVector.sub(desired, velocity);
    steer.limit(maxforce);
    applyForce(steer);
  }

  // if the particles come within a certain distance
  // then interact by pulsing a circle.
  // The pulse effect should be a circle that grows until
  // it reaches a set radius, then disappears.

  // The pulsing circle will be centered at the particle's
  // x,y coordinates at each step.
  void interact(Particle other, float radius) {
    //if (id == other.id) {
    // continue; // skip
    //}
    
    float d = PVector.dist(pos, other.pos);

      // trigger the interaction.
    if (d <= radius) {
        interacting = true;
        other.interacting = true;
        
        iradius = 0;
        other.iradius = 0;
    } // if
  } // end interact function.

  void update() {
    velocity.add(acceleration);
    velocity.limit(maxspeed);
    pos.add(velocity);
    acceleration.mult(0);
  }

  void display() {
    fill(colEllipse);
    noStroke(); 
    ellipse(pos.x, pos.y, 
      r, r);

    if (interacting) {
      if (iradius < radius) {
        noFill();
        stroke(255, 255, 0);
        ellipse(pos.x, pos.y, 
          iradius, iradius);
        iradius += pulseSpeed;
      } else {
        interacting = false;
      }
    }
  } // end display function.
  //
} // end Particle class.
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 24, 2020, 6:31pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/10 "2020-03-24T18:31:10Z")

</div>

No, this is very wrong…

The nested for-loops is ONLY for the question of collision, NOT for the other parts of draw…

```auto
      // interact with each each other
      particle.interact(other, 2);

```

(the consideration is mainly for many particles, with 2 particles it doesn’t matter)

You did rewrite interact() - basically without a for loop, Well done.

```auto
  Particle pt; 

  for (int i=0; i<particles.size()-1; i++) {
   pt = particles.get(i)
    for (int j=i+1; j<particles.size(); j++) {
      // interact with each each other
      pt.interact(particles.get( j ), 25);
    } 
  }

```

---

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 24, 2020, 6:42pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/11 "2020-03-24T18:42:15Z")

</div>

Got it. Here is now my `draw()` function

```auto
void draw() {
  background(0);

  // make particles seek and interact with each other  
  for (int i=0; i<particles.size()-1; i++) {
    for (int j=i+1; j<particles.size(); j++) {
      Particle particle = particles.get(i);
      Particle other = particles.get(j);
      
      particle.seek(other.pos);
      other.seek(particle.pos);
      
      particle.interact(other, 25);
    }
  }

  // update physics and display
  for (Particle particle : particles) {
    particle.update();
    particle.display();
  }
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 24, 2020, 6:47pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/12 "2020-03-24T18:47:20Z")

</div>

much better

Well done

Did you try with 20 particles?

Chrisir

---

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 24, 2020, 6:55pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/13 "2020-03-24T18:55:40Z")

</div>

> [@Chrisir](#):
>
> Did you try with 20 particles?

Yes. With the current code, because the `iradius` is reset within the `interact()` function the effect keeps resetting, and therefore it doesn’t look like any effect is happening at all.

Next step is to focus on **these lines**

```Processing
iradius = 0;
other.iradius = 0;

```

**in here**

```Processing
void interact(Particle other, float radius) {

    float d = PVector.dist(pos, other.pos);

      // trigger the interaction.
    if (d <= radius) {
        interacting = true;
        other.interacting = true;
        
        iradius = 0;
        other.iradius = 0;
    } // if
  } // end interact function.

```

and introduce some logic where if a particle effect is currently in progress, don’t reset.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 24, 2020, 8:04pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/14 "2020-03-24T20:04:43Z")

</div>

> [@codingcomplexity](#):
>
> introduce some logic where if a particle effect is currently in progress, don’t reset.

something like

```auto
 if (d <= radius) {
   
   if( !interacting) {
       interacting = true;
       iradius = 0;
  }

   if( !other.interacting) {
       other.interacting = true;
       other.iradius = 0;
  }
  //
}

```

The ! means NOT

---

<div class="post-metadata">

**Author:** ![codingcomplexity](https://avatars.discourse-cdn.com/v4/letter/c/ed8c4c/32.png) [@codingcomplexity](https://discourse.processing.org/u/codingcomplexity)\
**Post date:** [March 24, 2020, 11:42pm UTC](https://discourse.processing.org/t/trigger-animation-effect-after-object-collision/18811/15 "2020-03-24T23:42:36Z")

</div>

> [@Chrisir](#):
>
> if (d \<= radius) { if( !interacting) { interacting = true; iradius = 0; } if( !other.interacting) { other.interacting = true; other.iradius = 0; } // }

That does the trick! @Chrisir thank you for your help, tips, and guidance with this. I learned a lot through the process.
