/*! \page helloCinderChapter5 Chapter 5: External Forces
\section personalSpace Personal space
At the end of the last section, we had a nice \c Particle emitter cursor trail. As you drag the cursor around, you leave a trail of hundreds of moving <tt>Particle</tt>s. Every one of those <tt>Particle</tt>s is responding to its initial starting velocity combined with a hint of \ref cinder::Perlin "Perlin" noise. Each \c Particle does its thing and is oblivious to what any of the <tt>Particle</tt>s are doing. Until now.\n
\n
We are going to implement a very basic repulsive force to each \c Particle. Every single \c Particle will push away every other \c Particle. We will do this by giving each \c Particle an acceleration vector called \c mAcc.\n
\n
Here is how it will work. From the \c ParticleController, we will iterate through all the <tt>Particle</tt>s. For each \c Particle, we check it against all other <tt>Particle</tt>s. If those two <tt>Particle</tt>s are close, they will push each other away more strongly than if the two <tt>Particle</tt>s are on opposite sides of the app window. We add that repulsion to the respective <tt>Particle</tt>s' \c mAcc vectors.\n
\n
Once we have iterated through all the <tt>Particle</tt>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.\n
\n
The abridged version of what each \c Particle will go through looks like this:
\code
mVel += mAcc;
mLoc += mVel;
mVel *= mDecay;
mAcc.set( 0, 0 );
\endcode
\n
We are also adding a new variable to represent the <tt>Particle</tt>'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 <tt>Particle</tt>s are really massy. I like my <tt>Particle</tt>s a little more floaty.
\code
mMass = mRadius * mRadius * 0.005f;
\endcode
\n
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.\n
\n
\section repulsion Basic Repulsive Force
\code
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 );
			}
		}
	}
}
\endcode
\n
Lets go through this step by step. First, you set up a for-loop that uses the \c list \c iterator to go through all the <tt>Particle</tt>s, one by one, in the order they are sorted in the list.
\code
for( list<Particle>::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 ){
\endcode
\n
Next, we create a second \c iterator that also loops through the <tt>Particle</tt>s, but it starts at one \c Particle ahead of the first <tt>iterator</tt>'s position. Put another way, if we are on \c Particle 15 in the first \c iterator, the second \c iterator will loop through <tt>Particle</tt>s 16 and higher. \c Particle 16 will \c iterate through \c Particle 17 and higher, etc.\n
\n
Put yet another way, imagine that we have 3 <tt>Particle</tt>s. Each \c Particle wants to repel every other \c 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 <tt>iterator</tt>s.
\code
list<Particle>::iterator p2 = p1;
for( ++p2; p2 != mParticles.end(); ++p2 ) {
\endcode
\n
Now that we are inside of the second \c iterator, we are dealing with a single pair of <tt>Particle</tt>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 \c length().
\code
Vec2f dir = p1->mLoc - p2->mLoc;
float dist = dir.length();
\endcode
\n
Here is where we run into our first problem. To do this repulsion force, we don't need the distance between the <tt>Particle</tt>s. We need the distance squared. We could just multiply \c dist by \c dist and be done with it, but we have another option.\n
\n
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 \c length() looks like this:
\code
sqrt( x*x + y*y )
\endcode
\n
You should try to avoid using \c 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 \c lengthSquared() method we can use. 
\code
Vec2f dir = p1->mLoc - p2->mLoc;
float distSqrd = dir.lengthSquared();
\endcode
\n
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.
\code
if( distSqrd > 0.0f ){
\endcode
\n
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.
\code
dir.normalize();
\endcode
\n
The first factor which determines how much push each \c Particle has on the other is the inverse of the distance squared. 
\code
float F = 1.0f / distSqrd;
\endcode
\n
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 \e adding the force divided by p1's mass.
\code	
p1->mAcc += ( F * dir ) / p1->mMass;
\endcode
\n
To find out p1's contribution to p2's total acceleration, you \e subtract force divided by p2's mass.
\code
p2->mAcc -= ( F * dir ) / p2->mMass;
\endcode
\n
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.\n
\n
Now we can turn on our repulsion. In our App class, before we tell the \c ParticleController to update all the <tt>Particle</tt>s, we trigger the <tt>ParticleController::repulseParticles()</tt> method. We can now run our code. \n
\n
\image html tutorial_part5_01.png
\n
Every single Particle pushes away its neighbors which causes the <tt>Particle</tt>s to spread out in a really natural manner. Here is a short video of the effect in action. \n
\Movie{tutorial_part5_01.mov,800,620}
\n
Ready for something special? Try this. Turn off the <tt>Particle</tt>'s ability to age. Turn off the \ref cinder::Perlin "Perlin" noise influence. And finally, put back the \ref cinder::ChannelT "Channel"-based variable radius. Once you add a few thousand <tt>Particle</tt>s, you should get back something like this. \n
\Movie{tutorial_part5_02.mov,800,620}
\n
During the course of this tutorial, we have managed to create a robust stippling algorithm almost by accident. We started with a simple image loading example and some randomly moving circles. After a few minor iterations, we have written a pretty cool program that will dynamically stipple images by simply combining a particle engine with a repulsive force.\n
\n
Hopefully you are inspired and anxious to continue exploring. This is not an end - there is so much more to do. Try adding a third dimension to this project. Experiment with different types of external and internal forces. Try mixing different \e flavors of Particles together. Find new ways to control the Particles such as microphone input or webcam. Trace the path the particles travel over time. Draw the connections between neighboring particles. Or maybe don't draw the particles at all and instead only draw their collisions. So many options! So many paths to explore. And it all started from an empty black window.\n
\n
Where to now? Have a peek in the <a href="http://libcinder.org/gallery/">Gallery</a> to see what others are up to with Cinder, or read more about the <a href="http://libcinder.org/features/">Features</a> for ideas on what to explore. If you have questions, comments, ideas, or work to share, hop on over to the <a href="http://forum.libcinder.org/#AllForums">Cinder forum</a>. On behalf of its whole community, let me say that we're excited you've taken the time to check out Cinder, and we hope you'll come join in.
\n

*/
