In today's lab we will build an animated simulation of particle
movement. Begin by creating a new package (Eclipse) or folder (Thonny) for today called lab12
and then copy and paste these starting files into the package:
An initial goal for today's lab is to model a single particle moving around a constrained environment. The starting code provides the environment, but we need to create a particle and visualize its movement. Let's begin with the even simpler task of visualizing a single particle.
Our first iteration requires updates to both the simulation engine and to the model of the particle. Proceed as follows:
render that
receives a canvas (in addition to self) and uses the canvas and
instance variables to draw a circular representation of the
particle. You can use: canvas.create_oval(self._x - self._radius,
self._y - self._radius,
self._x + self._radius,
self._y + self._radius,
fill = self._color)
self.p1 which is an
instance of the Particle class. This particle should be a default
particle.
self.p1.render(self.canvas) for
this step.
Verify that a single particle appears on the canvas before proceeding.
A particle appearing is all well and good, but let's make this particle move!
To make a particle appear to move around the screen, we need to set up an animation loop, as well as allow the particle to change its location (according to its velocities). Proceed as follows:
move that
receives a canvas (in addition to self).
self._x
+= self._velX).
self.canvas.delete(ALL)self.canvas.after(50, self.render) self.render()By the end of this step, a single particle should bounce around the screen.
A single particle moving around the screen is great, but its way more fun to have lots of particles bouncing around together.
We could write our program to use a fixed number of particles, but to maximize our fun, let's create a button that will let the user add random particles to the screen. Note: We will not need to update our Particle class at all, because we already have a working model of a particle. We only need to update our simulation driver. Proceed as follows:
self.p1
with the creation of an empty list called self.p_list'Add
particle', and associate clicking the button with a method called
self.add_particle
add_particle:
self.p_list
self.canvas.delete(ALL).
self.p_list
self.canvas.after(50, self.render)Verify that each time you click the add particle button, a new, random particle is added to the screen.
As fun as it is to get particles moving around, we'd like to increase the interactive capabilities of our simulation by allowing the user to remove a particle when it is clicked.
To remove a particle from our animation, we'll need the ability to determine how close a mouse click is from a particle. Since a particle keeps track of its own location, we'll need accessors to retrieve this information so we can compute the distance between a mouse event and a particle in our simulation. Proceed as follows:
self.canvas.bind('<Button-1>', self.check_remove_particle)
check_remove_particle
that implements the following algorithm.
event in
addition to self.Note that you can
event.x and event.y to get
the location of the mouse event.
copy = self.p_list[:] )
You'll notice that you have to click very carefully to remove a particle (it will be much easier on more slowly moving particles). This is due to the interaction between the animation loop and the event loop. As long as you can get some particle to disappear, you're good to go on.
As a final iteration, we'd like to modify the particles to interact with one another by bouncing off one another. This requires that you change both the Particle class, whose objects will need to know when they are "hitting" other objects, and the simulation engine, which must ask each particle that is hitting another particle to "bounce" off of that particle.
Add the following code to your Particle class: collision code. The constant should be added above the definition of the class, and then the two methods should be added to the Particle class. This code implements collision detection and bouncing behavior; read through the documentation to get an idea of how it works.
Now, update the algorithm for the animation loop in your constructor as follows.
self.canvas.delete(ALL).
p1
in self.p_list
p2 of self.p_list:
p2
(using p1.bounce(p2)).
self.canvas.after(50).
self.canvas.update().
This new step 1.c bounces the current ball off of each of the other
balls. If there is no overlap, the call to bounce()
does nothing.
Submit the final version of your particle simulation; the intermediate steps along the way are not required. We will grade this exercise according to the following criteria:
ParticleSimulation - This class should
construct the interface correctly and implement its behavior as
specified.
Particle - This class should encapsulate
the required particle attributes and behaviors.
If you’re working on a lab computer, don’t forget to log off of your machine when you are finished!