The top of the world should have 4 buttons (you are being provided with a GenericButton class) across it, labeled “Load”, “Merge”, “Save”, and “Pause”; the actions when each of these is clicked are described below:
• Load. This should first remove all existing charged particles from the world. It should then use a FileDialog to select a file for reading; this file will specify charged particles to add to the world, with each charged particle specified in the following format:
<particle_type> <mass> <radius> <x_position> <y_position>
where:
– <particle_type> is a String. If the String starts with the # character, the rest of the line should be ignored. The only two other options for this String would be repeller or attractor, representing whether the 4 integer numbers that follow specify a repelling charged particle or an attracting charged particle (respectively). Note that these strings should be case insensitive, so there are many possibilities including (but not limited to): RePeLler, attRacTor, ATTRACTOR, repeller, REPELLER, ...
– <mass> is an integer. This number represents the mass of the charged particle. For those who are “Physics impaired”, this value is similar to (but not quite the same as) weight.
– <radius> is an integer. This number represents the radius of a charged particle. Note that all charged particles are circles (technically, they are spheres, but our simulation is in 2-D). Also note that the diameter of a charged particle would be twice this value.
– <x_position> and <y_position> are integers representing the location of this charged particle. Assume that (0,0) is in the upper left corner of your world, and that increas- ing x and y values move to the right and down (respectively). Note that this follows Greenfoot’s coordinate system.
So, consider the following examples:
Attractor 10 7 50 100
The above would give a new Attracting Charged particle of radius 7 and mass 10, found 100 pixels from the top of the world and 50 pixels from the left edge of the world.
# the following is a repeller.
repeLLer 7 10
100 15
The above would specify a repelling charged particle of mass 7 and radius 10, to be placed 100 pixels from the left edge of the world and 15 pixels from the top of the world.
– Note that Attractors should be drawn as a a circle of the specified radius, and should be blue in color. Repellers should be red in color and similarly be circles of the specified radius values.
– Also, you may assume that no input file will contain invalid data.
• Merge. This is the equivalent of load, except any existing charged particles should not be
removed first.
• Save. This should use a FileDialog to select a file. One line should then be written out to the file for each charged particle currently in the world. The format should match that of the load option. In other words, a file saved through this option should be loadable through the load option. Remember that load is expecting integer numbers, but the current position of any charged particle is likely to be a floating point number.
• Pause. When clicked, this should change the text of this button to UnPause and then cause the entire simulation to stop until this button is clicked again. If the button is clicked when the world is paused (i.e. when the button reads “UnPause”), then the text should be changed back to Pause and the simulation should continue.
3 Simulation of Charged Movement
Each charged particle behaves as follows:
• it starts with a speed in the x and the y direction of zero.
• in every call to act, every other charged particle in the world moves this charged particle. Attractors pull this charged particle towards themselves, while repellers push this charged particle away. Don’t Panic! – one of the great things about being a (beginning) Computer Scientist is that someone else gives you the math for this, and this case is no exception. Consider the following ideas, assuming that p is the current particle we are considering (to be pushed and/or pulled) and o is one of the particles that would be pushing or pulling p:
– First, figure out the distance between p and o as
d = √(px − ox)2 + (py − oy)2
where (px, py) are the coordinates of particle p and (ox, oy) are the coordinates of particle o.
– if the distance between the two is no more than the sum of the radius of both particles, then the particles are touching. In this case, o is considered to have no impact on particle p.

– (noting you should not always get to this step, based on what you figured out in the last step,) calculate
∆x = ox − px ∆y = oy − py
and
– Next, calculate Θ (read “theta”) according to the following table:
∆x ∆y Θ
>0 — tan−1 ( ∆y ) ∆x
<0 — π + tan−1 ( ∆y ) ∆x
0  <0 3π/ 2
0 ≥0 π/2
Please don’t forget that in Java, π is Math.PI and you can use the Math.atan method to calculate tan−1() (note that tan−1() is NOT 1 !!!!)
– Next, figure out the magnitude of the force between these two particles as F = pm · om
d2
where om is the mass of the “other” particle and pm is the mass of “this” particle.
– Then figure out how much of this force is acting in the x direction: Fx = F · cos (Θ)
and in the y direction:
Fy = F · sin (Θ)
Again, feel free to use the Math.cos and Math.sin methods.
– as you calculate F , keep a running total Fsum of these by adding each F to the total xxx
when the other particle is an attractor and subtracting F from Fsum when the other xx
particle is a repeller. Keep a similar sum Fsum for the F values. yy
– After you have calculated the above running sum for every other particle, figure out ax, the resulting acceleration in the x direction, as:
F sum x
pm
F sum y
pm
– add the speed in the x direction to the current particle’s x location. Similarly, add the speed in the y direction to the current particle’s y location.
tan()
ax =
and ay, the resulting acceleration in the y direction, as:
ay =
– add ax to the speed in the x direction of this particle. Similarly, add ay to the speed in
the y direction of this particle.

• finally, add code to make sure that a particle “bounces off” of the sides of the World when it hits them. Essentially, a particle will negate its corresponding speed value when it hits a side of the World. Make sure this happens as soon as a particle touches the edge of the world, not when half of the particle has already gone over the edge of the world.
Note that most of the calculations involved above result in floating point values, including the current location(s) of particle(s). So, Greenfoot’s default location/movement code will not suffice here.
