Particle attraction simulation on the Wii - 01/02/2009, 17:14
A few days ago I decided to do a small particle attraction physics simulation and run it inside the Wii, which can be seen in the following video:
( http://www.youtube.com/watch?v=YVhExgbaLXo )
Here's how the attraction between particles is calculated:
According to the Law of Universal Gravitation (young children's version - ask your nearest physicist),
"Every object in the Universe attracts every other object with a force directed along the line of centres for the two objects that is proportional to the product of their masses and inversely proportional to the square of the separation between the two objects"
The formula for this sentence is expressed as follows:
Where F is the gravitation force, m1 and m2 are the two object's masses, r is the distance between both objects' centres and G is the Universal Gravitation Constant.
Now, here we want to know how each object affects another object. And because of the iterative nature of computer simulations, what we really want to know is not the force, but rather the acceleration an object causes upon another.
So let's do this for object 1 -- divide both sides of the equation by m1.
Now we know how object 2 accelerates object 1.
To know how object 1 accelerates object 2, divide both sides of the equation by m2.
To make it run faster on the computer, what we do is avoid multiplying object 1's mass in the equation, therefore we have
Since we're talking about not just two objects, but many, what we must do is calculate how every object accelerates object 1, and sum all these accelerations.
Note that r will be different with each object, so it can't be left out of the sum.
Now, there is another slight computing detail here - for a computer, dividing G over r2 is usually as expensive as dividing 1 over r2. Therefore we can compute G/(r2) and apply it for both objects, by storing G/(r2) in another variable and then multiplying for each mass separately.
To avoid iterating twice on each object, we can re-write the equation as:
When does 3D come into play?
Well, the Law of Universal Gravitation does state:
"... with a force directed along the line of centres .."
Easy enough. Let's define the direction by setting a vector "vji" that goes from the centre of object i to the centre of object j. Then, let's divide its components by a value such that the "size" of the vector will be 1.
Coincidentally (or perhaps by definition) that value will be r.
To calculate the acceleration direction for object j, we simply invert vji's direction.
-.-.- Now for the computer programming part -.-.-.-
As a program, it operates in the following way:
1.Set up variables, display mode, etc.
2.Set up the "black hole" - set coordinates to the origin and mass to 200. Set colour to black. Set speed to 0 in all directions (not moving).
3.Initialise cube data (random mass between 1 and 20, random starting positions between -10 and 10 in all three coordinates: right-hand system, y being vertical. Random colours excluding black).
4.Set random speed to each cube -- since we want the objects to move in a direction tangent to the black hole, the cube's position coordinates get compared. The coordinate with the largest absolute value defines which coordinate will get set to 0 in the object's speed (for example, for an object with position (4,-5,2) and speed (3,6,8), the position coordinate with the largest absolute value is y. Therefore the y speed component will be set to 0 (3, 0, 8).
Set the acceleration for the current object ("object i") to 0.
For all objects i+1 as j, (if object j has not been captured by black hole, otherwise skip to next j)
1.Calculate vji and r
2.(if object i is the black hole and r < 0.3, mark object j as "captured")
3.Calculate G/(r2) due to object j
4.Save in variable k
5.Multiply k by mi
6.Add to ai
7.Multiply k by mj
8.Add to aj
9.Go on with next object j
After all objects' accelerations have been calculated, speed and position must be updated (see in a previous post for justification)
vi = vi + ai/(time_elapsed_for_current_frame)
pi = pi + vi/(time_elapsed_for_current_frame)
When all objects are either captured by the black hole or have gone very far away (and will probably never come back), initialise everything again and repeat.
Source code will follow soon - after submitting the MotorJ framework update...