/**/ CS100, Spring 2000, Project 5: Following the Bouncing Ball /**/ /**/ Due at the START of lecture, THURSDAY, March 30. /**/ /**/ Early submissions (any day before the due date) MUST be turned in to a /**/ consultant in Carpenter -- make sure they log your submission! If you /**/ submit Project 5 on or before Wednesday and it earns 4/4 or better, we /**/ will give you 1 bonus point. /**/ /**/ Changes from the earlier draft are marked with "/**/" on the far left. /**/ The exception is the change from "Project4" to "Project5" is not marked. =============================================================================== Part 1: Goals/Concepts =============================================================================== + Classes, objects, methods + Graphics + Simulation of ideal gas law + Incremental problem solving + Motivation for arrays =============================================================================== Part 2: Overview =============================================================================== In this program you will simulate molecular 2-dimensional motion and test whether the ideal gas law applies to the simulation. In this setting, the ideal gas law is P V --- = constant, N T where P = pressure, V = area, N = number molecules, T = temperature. Note: Part 3 reviews these and other basic physical parameters. ( The ideal gas law is usually stated as PV=nRT, where V is the volume and n is the number of moles. Here, V is area because we're in two dimensions and we fold Avogadro's number 6e23 into the constant because: (1) We haven't yet taught you how to deal lots of variables/objects. (2) A mole is just too darn big! Most computers don't even have 1e9 bytes. ) You will have a "World," which is a square container, containing 3 molecules of known mass, size, and color, but random positions and velocities. The molecules move around and elastically collide (bounce perfectly) with each other and the 4 rigid walls of the container. You will measure the average pressure on the top wall of the container as the time-average momentum applied to the top wall by molecules colliding into it. Thus, the program keeps track of the elapsed time and cumulative momentum applied by Molecules colliding into the top wall. You will measure temperature as the average kinetic energy of all the molecules. (You might recall from physics that if all molecules have the same mass, then temperature is a function of the root mean square velocity. Recall that the formula for Vrms was on Prelim 1, Prob. 1.) To let you see what is happening in the simulation, you will graphically animate the molecules moving around. The simulation runs until the user stops the program. (Recall from the webpage, use Quit from the Apple menu on a Mac, press Ctrl-C in the Console window on a PC.) =============================================================================== Part 3: Physics Review and Simulation Terminology (Time Step) =============================================================================== Physics Review We use generic units: + Mass is measured in "units of mass". + Time is measured in seconds. + Distance is measured in "units of distance". Thus, + Area = width * height. + Velocity = distance / time. + Momentum = mass * velocity. + Kinetic energy = .5 * mass * (velocity squared). + Force = average rate of change in momentum. NOTE: The average is with respect to time: Compute the cumulative change in momentum and divide by the total elapsed time. + Pressure = force / distance. NOTE: Normally pressure is force / area, but our container is 2-dimensional, so we must drop down a dimension. + Temperature = average kinetic energy. This average is the mean at each time step of the kinetic energies of the Molecules. (Recall: In classical physics, temperature of an ideal gas is proportional to average kinetic energy.) What is a time step? Think of the simulation as being like a movie. Each movie frame is a snapshot in time. Stuff happens between one frame and the next. That constitutes one time step. Within each time step, all the molecules are moved. Movies can be filmed at different rates: slow-motion, regular, and elapsed time. The difference is the amount of time between each frame. That is the size of the time step. When computing the next position of a molecule, the (size of the) time step matters: if it is traveling 6 meters per second, then in a time step of 2 seconds it travels 12 meters, but in a time step of .5 seconds it travels only 3 meters. =============================================================================== Part 4: How to get Started =============================================================================== 1. Read the entire assignment to get a gist for what is required. 2. Repeat Step 1 as required to identify the different pieces and how they fit together. 3. Obtain Project5.java from Part 5 of this write-up and run it. 4. Define the Molecule class incrementally and incorporate it into Project5.java. For what to do, see Part 7: Molecules. 5. (Really part of Step 4.) Modify the World class to move and draw the Molecules and to print after each move the statistics specified in the comments, namely P, T, and (PV)/(NT). /**/ See also the Tips/Hints for Project 5 on the Projects webpage /**/ for a more detailed sequence of steps you should take. =============================================================================== Part 5: Project5.java =============================================================================== // Here is the file Project5.java that contains the overall structure from which // to start the project. Places where you have to add code are marked with a // comment starting with "(*)". import java.text.DecimalFormat; import java.awt.*; class Molecule { // (*) Your code for class Molecule goes here -- see Part 7: Molecules } // a World is a square container containing Molecules class World extends Frame { double step = 0.5; // the length of time of each time step double size; // width=height of container double hit = 0.0; // cumulative vertical momentum applied to the top wall double time = 0.0; // elapsed time from start of simulation double P; // pressure double V; // area (not volume) double N; // number of molecules double T; // temperature measured as average kinetic energy // (*) your declarations for the 3 Molecules m1, m2, m3 go here // create a new world of size s public World(int s) { size = s; V = size*size; N = 3; // (*) your code to create the 3 Molecules goes here show(); // show; apparently needed to getInsets setSize(getInsets().left+getInsets().right+(int)size, getInsets().top+getInsets().bottom+(int)size); setBackground(Color.white); } // move each Molecule one time step public void move() { // (*) your code goes here } // draw all the Molecules safely synchronized public void mypaint(Graphics g) { g.translate(getInsets().left,getInsets().top); g.clearRect(0,0,(int)size,(int)size); // erase old molecules // (*) your code to draw the Molecules goes here } // draw all the Molecules -- call mypaint to be safe: // need the "synchronization". public void paint(Graphics g) { mypaint(g); } } public class Project5 extends Thread { public void run() { /**/ int worldsize = 150; // size of world (the container) /**/ World w = new World(worldsize); while (true) { try { sleep(20); } catch (InterruptedException e) { } // perform one time step w.move(); w.paint(w.getGraphics()); // (*) your code to display P, T, (PV)/(NT) goes here /**/ // You may compute those stats here or in World.move(). } } public static void main(String[] args) { new Thread(new Project5()).start(); } } Note: drawing might be messed up for the first few seconds or so. =============================================================================== Part 6: Graphics =============================================================================== /**/ Refer to Project 4. /**/ /**/ (See also lecture and section notes, and online examples.) =============================================================================== Part 7: Molecules =============================================================================== Define a class $Molecule$ with the following instance variables and methods: + $double mass$ + $double px, py$ position -- center of the Molecule. + $double vx, vy$ velocity + $double radius$ + $Color color$ /**/ + $World world$ -- the "world" (container) where the molecule "lives" /**/ + $Molecule(Color c, int m, int r, World w)$ /**/ Create a Molecule with color $c$, radius $r$, and mass $m$, /**/ positioned randomly in World $w$, with random speed -5<=vx,vy<=5. /**/ /**/ [Remark: in general programming, the order of parameters can vary from /**/ context to context. It happens here that the order of parameters in the /**/ constructor matches the order used to specify molecule characteristics /**/ in Part 9.] + $double energy()$ Return the kinetic energy of the molecule. /**/ + $void move()$ /**/ Move the molecule (update the position), /**/ assuming no collisions with another molecule. /**/ Deal with collisions with walls -- /**/ keep the molecules inside the World (container)! /**/ Remember to use the timestep $step$ from the World. /**/ + void collide(Molecule m)$ /**/ Test whether the molecule would collide with another molecule $m$; /**/ if so, alter velocities appropriately. Remember to account for $step$. /**/ /**/ [Remark: In Part 8, the discussion of collisions involves two molecules. /**/ The variables for one molecule are indexed by "1", the variables for the /**/ other molecule are indexed by "2". You might find it convenient to name /**/ the parameter $m2$ instead of $m$, but make sure you do not confuse it /**/ with the instance variables $m1,m2,m3$ of the World. In general, /**/ variable names should be chosen for maximum clarity. Here, it is not so /**/ clear what names are clearest.] + $void paint(Graphics g)$ Draw the molecule as a filled-in disk with the specified $color$, $radius$, and position (center). Note: There is no gravity. The only iteractions are collisions between two molecules and collisions between a molecule and a wall. Note: $Math.random()$ yields a random floating point number in the range 0..1. =============================================================================== Part 8: Collisions =============================================================================== Tip: don't work on collisions until everything else is working. For simplicity, let us pretend that two molecules collide in the next time step if they have overlapping *extents*. An *extent* of a molecule is the smallest rectangle that encloses the start and end position of that molecule in a time step. For example, if a Molecule with radius r starts at (x,y) and ends at (x',y'), the x-extent is [Math.min(x,x')-r, Math.max(x,x')+r] and the y-extent is [Math.min(y,y')-r, Math.max(y,y')+r]. NOTE: See below for what to do with multiple collisions. Below we use the notation (a,b) = (A,B) to abbreviate a=A and b=B. Here is a formula (derivation shown elsewhere) for computing the new velocities of two molecules that collide: (dvx1, dvy1) = ( (s/m1) fx, (s/m1) fy) and (dvx2, dvy2) = (-(s/m2) fx, -(s/m2) fy). where [2 (fx * (vx2-vx1) + fy * (vy2-vy1)) ] s = --------------------------------------. (fx * fx + fy * fy) (1/m1 + 1/m2) m1 and m2 are the masses /**/ (x1,y1) and (x2,y2) are the ORIGINAL positions (vx1,vy1) and (vx2,vy2) are the original velocities (vx1+dvx1, vy1+dvy1) and (vx2+dvx2, vy2+dvy2) are the updated velocities (fx,fy) = (x2-x1, y2-y1) is the direction along which molecules collide [The formula above assumes the molecules have just collided and are touching; go ahead and use it as long as the extents overlap -- do NOT solve for the point of contact.] Use this algorithm for two Molecules: if the extents overlap, then update their velocities using the formula above BUT leave their positions unchanged. Use this algorithm for multiple Molecules (in our case, for 3 Molecules): apply the algorithm above between each pair of molecules in any order; test each pair with each other only once. NOTE: The multi-molecule algorithm above assumes that each Molecule collides with at most one other Molecule within a time step. If there are multiple collisions, it does something "funky" but hopefully not too bad. /**/ The way the World moves the molecules in a time step should be as follows: /**/ + First, test all molecules for collisions using the algorithm above. /**/ then, /**/ + Second, move all molecules assuming no collisions happen. =============================================================================== Part 9: Worlds (square containers) =============================================================================== Complete the code for the following methods of class $World$: + The constructor $World(int s)$ should create a World of size $s$ containing 3 Molecules: a red Molecule of mass 1 and radius 4 a green Molecule of mass 4 and radius 5 a blue Molecule of mass 16 and radius 7 Do not use input. + The method $void move()$ must move all the molecules. This includes dealing with collisions. + The method $void mypaint(Graphics g)$ must draw all the molecules. HINTS: + Update instance variables of the World as appropriate, e.g. $P$. + Every time a Molecule hits the upper wall, adjust $hit$ to account for the change in vertical component of the Molecule's momentum. + Use average (with respect to time) momentum for the pressure on the top wall. =============================================================================== Part 10: Bonus =============================================================================== /**/ Note: do NOT attempt any bonus points until *after* you have the core /**/ project entirely working. Also, core questions have priority over bonus /**/ questions. Remember (a) bonuses are *true* bonuses, and (b) core points /**/ are what primarily determine your grade. /**/ /**/ + Do not print the statistics P, T, (PV)/(NT); /**/ instead, draw them in a separate window. /**/ /**/ + Use arrays to create 60 Molecules -- 20 of each kind. /**/ /**/ + Make all instance variables $private$; /**/ define and use "getter" methods as appropriate/necessary. =============================================================================== Part 11: What to hand in =============================================================================== /**/ Follow the submission guidelines on the web-page. Turn in the following: /**/ /**/ + A printout of *all* the code. /**/ /**/ + Screen snapshot showing the molecules and statistics --make sure all /**/ windows are clearly visible!-- for simulations with Worlds of size 100, /**/ 200, and 400.