At the end of the last section, we had a nice `Particle`

emitter cursor trail. As you drag the cursor around, you leave a trail of hundreds of moving `Particle`

s. Every one of those `Particle`

s is responding to its initial starting velocity combined with a hint of Perlin noise. Each `Particle`

does its thing and is oblivious to what any of the `Particle`

s are doing. Until now.

We are going to implement a very basic repulsive force to each `Particle`

. Every single `Particle`

will push away every other `Particle`

. We will do this by giving each `Particle`

an acceleration vector called `mAcc`

.

Here is how it will work. From the `ParticleController`

, we will iterate through all the `Particle`

s. For each `Particle`

, we check it against all other `Particle`

s. If those two `Particle`

s are close, they will push each other away more strongly than if the two `Particle`

s are on opposite sides of the app window. We add that repulsion to the respective `Particle`

s' `mAcc`

vectors.

Once we have iterated through all the `Particle`

s, we add the acceleration to the velocity. Then we add the velocity to the position. We decay the velocity. We reset the acceleration. And we repeat.

The abridged version of what each `Particle`

will go through looks like this:

mVel += mAcc; mLoc += mVel; mVel *= mDecay; mAcc.set( 0, 0 );

We are also adding a new variable to represent the `Particle`

's mass which is directly related to the radius. The actual relationship is a matter of personal taste. Once we make use of the mass variable, you might find you like how things behave if your `Particle`

s are really massy. I like my `Particle`

s a little more floaty.

mMass = mRadius * mRadius * 0.005f;

This formula is not based on anything other than trial and error. I tried setting the mass equal to the radius. Didn't like that. I tried mass equal to radius squared. Didn't like that. I eventually settled on taking a fraction of the radius squared.

void ParticleController::repulseParticles() { for( list<Particle>::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 ) { list<Particle>::iterator p2 = p1; for( ++p2; p2 != mParticles.end(); ++p2 ) { Vec2f dir = p1->mLoc - p2->mLoc; float distSqrd = dir.lengthSquared(); if( distSqrd > 0.0f ){ dir.normalize(); float F = 1.0f/distSqrd; p1->mAcc += dir * ( F / p1->mMass ); p2->mAcc -= dir * ( F / p2->mMass ); } } } }

Lets go through this step by step. First, you set up a for-loop that uses the `list`

`iterator`

to go through all the `Particle`

s, one by one, in the order they are sorted in the list.

```
for( list<Particle>::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 ){
```

Next, we create a second `iterator`

that also loops through the `Particle`

s, but it starts at one `Particle`

ahead of the first `iterator`

's position. Put another way, if we are on `Particle`

15 in the first `iterator`

, the second `iterator`

will loop through `Particle`

s 16 and higher. `Particle`

16 will `iterate`

through `Particle`

17 and higher, etc.

Put yet another way, imagine that we have 3 `Particle`

s. Each `Particle`

wants to repel every other `Particle`

. First round, p1 and p2 repel each other, and then p1 and p3 repel each other. Second round, we already handled all of p1's interactions so we move on to p2. Since p2 has already interacted with p1, all that is left is for p2 and p3 to repel each other. That is the logic for the nested `iterator`

s.

```
list<Particle>::iterator p2 = p1;
for( ++p2; p2 != mParticles.end(); ++p2 ) {
```

Now that we are inside of the second `iterator`

, we are dealing with a single pair of `Particle`

s, p1 and p2. We know both of their positions so we can find the vector between them by subtracting p1's position from p2's position. We can then find out how far apart they are by using `length()`

.

Vec2f dir = p1->mLoc - p2->mLoc; float dist = dir.length();

Here is where we run into our first problem. To do this repulsion force, we don't need the distance between the `Particle`

s. We need the distance squared. We could just multiply `dist`

by `dist`

and be done with it, but we have another option.

When finding out the length of a vector, you first find out the squared distance, then you take the square root. The code for finding the `length()`

looks like this:

sqrt( x*x + y*y )

You should try to avoid using `sqrt()`

when possible, especially inside of a huge nested loop. It will definitely slow things down as the square root calculation is much more processor-intensive than just adding or multiplying. The good news is there is also a `lengthSquared()`

method we can use.

Vec2f dir = p1->mLoc - p2->mLoc; float distSqrd = dir.lengthSquared();

Next, we make sure the distance squared is not equal to zero. One of the next steps is to normalize the direction vector and we already know that normalizing a vector with a length of zero is a bad thing.

```
if( distSqrd > 0.0f ){
```

Here is the sparkling jewel of our function. First, you go ahead and normalize the direction vector. This leaves you with a vector that has a length of one and can be thought of as an arrow pointing from p2 towards p1.

dir.normalize();

The first factor which determines how much push each `Particle`

has on the other is the inverse of the distance squared.

```
float F = 1.0f / distSqrd;
```

Since we already know that force equals mass times acceleration (Newton's 2nd law), we can find p2's contribution to p1's total acceleration by *adding* the force divided by p1's mass.

p1->mAcc += ( F * dir ) / p1->mMass;

To find out p1's contribution to p2's total acceleration, you *subtract* force divided by p2's mass.

p2->mAcc -= ( F * dir ) / p2->mMass;

If this all seems confusing to you, worry not. It still confuses me from time to time. With a little bit of practice, this code will start to feel more familiar.

Now we can turn on our repulsion. In our App class, before we tell the `ParticleController`

to update all the `Particle`

s, we trigger the `ParticleController::repulseParticles()`

method. We can now run our code.

Every single Particle pushes away its neighbors which causes the `Particle`

s to spread out in a really natural manner. Here is a short video of the effect in action.