Source Code for Boyle's Law Applet



import java.awt.*;
import java.applet.*;
import java.lang.*;

public class Boyle extends Applet
{
         Graphics  bG;                    // Graphics buffer
         Image     bI;                    // Image buffer
         Graphics  sG;                    // Display

         Color     background = new Color(128, 128, 255); // Background color
         Color     inside     = new Color(255, 255, 255); // Tank color
         Color     time       = new Color(0, 0, 255);     // Time gauge color
         Color     ball       = new Color(255, 0, 255);   // Ball color
         Color     wall       = new Color(0, 0, 0);       // Wall color

         Font      font       = new Font("Courier", Font.PLAIN, 12);

         int       center     =  100;                     // Tank center
         int       radius     =   80;                     // Tank radius
         int       nballs     =   20;                     // Number of balls
         int       nsteps     = 1000;                     // number of steps
         int       speed;                                 // Ball speed
         int       running    =   0;                      // 1 for running
         int       bounces;                               // Count bounces;
         int       i, j, k, ix, iy;

         double    bx[] = new double[100];                // ball x coord   
         double    by[] = new double[100];                // ball y coord   
         double    vx[] = new double[100];                // ball vel x coord   
         double    vy[] = new double[100];                // ball vel y coord 
         double    s, x, y; 

         public void init()
         {
              bI = createImage(this.size().width, this.size().height);
              bG = bI.getGraphics();      // Set up graphics buffer
              drawbackground();
         }

         public void paint(Graphics g) 
         {
              g.drawImage(bI, 0, 0, this);
              sG = getGraphics();                         // Get display
         }

         public void update(Graphics g)
         {
              g.drawImage(bI, 0, 0, this);
         }

         public void drawbackground()
         {    
              bG.setColor(background);
              bG.fillRect(0, 0, 421, 201);
              bG.setColor(wall);
              bG.fillOval(center-radius-5, center-radius-5, 
                          2*radius+11, 2*radius+11);
              bG.setColor(inside);
              bG.fillOval(center-radius-1, center-radius-1, 
                          2*radius+3, 2*radius+3);
              bG.fillRect(210, 20, 91, 21);
              bG.fillRect(210, 50, 91, 21);
              bG.fillRect(210, 80, 91, 21);
              bG.fillRect(320, 20, 91, 21);
              bG.fillRect(320, 50, 91, 21);
              bG.fillRect(320, 80, 91, 21);
              bG.fillRect(210, 110, 201, 20);
              bG.fillRect(210, 140, 201, 20);
              bG.fillRect(210, 170, 201, 20);
              bG.setFont(font);
              bG.setColor(wall);
              bG.drawString("Rad 1 Sp 1", 216, 35);
              bG.drawString("Rad 2 Sp 1", 216, 65);
              bG.drawString("Rad 4 Sp 1", 216, 95);
              bG.drawString("Rad 1 Sp 2", 326, 35);
              bG.drawString("Rad 2 Sp 2", 326, 65);
              bG.drawString("Rad 4 Sp 2", 326, 95);
        }

        public boolean mouseDown(Event evt, int x, int y)
        {
             if (running == 1)
                { return true; }
             if ( (210 < x) && (x < 301))
                { speed = 1;   }
             if ( (321 < x) && (x < 411)) 
                { speed = 2;   }
             if ( (20 < y) && (y < 41))
                { radius = 20; }
             if ( (50 < y) && (y < 71))
                { radius = 40; }
             if ( (80 < y) && (y < 101))
                { radius = 80; }
             simulate();
             return true;
       }

       public void simulate()
       {
            double    sine, cosine, mag, tx, ty;
            double    ax, ay, cx, cy, mx, my;            // For bisection method
    
            j = 0;
            running = 1;
            bounces = 0;            
            drawbackground();
            bG.setColor(time);
            bG.fillRect(210, 140, 201, 20);
            sG.drawImage(bI, 0, 0, this);
            bG.setColor(ball);
            for (i = 0; i < nballs; i = i + 1)
            {   x = 10;
                y = 10;
                while (x*x + y*y > 0.99)
                {   x = 2.0 * java.lang.Math.random() - 1.0;
                    y = 2.0 * java.lang.Math.random() - 1.0;
                }
                bx[i] = radius * x;
                by[i] = radius * y;
                ix = (int) java.lang.Math.round(bx[i]);
                iy = (int) java.lang.Math.round(by[i]);
                bG.fillOval(center + ix - 1, center + iy - 1, 3, 3);
                x = 0.0;
                y = 0.0;
                while (x*x + y*y < 0.1)
                {   x = 2.0 * java.lang.Math.random() - 1.0;
                    y = 2.0 * java.lang.Math.random() - 1.0;
                }
                s = java.lang.Math.sqrt(x * x + y * y);
                vx[i] = speed * x / s;
                vy[i] = speed * y / s;
            }  
            sG.drawImage(bI, 0, 0, this);
            for (k = 0; k < nsteps; k = k + 1)
            {
               drawbackground();
               bG.setColor(time);
               bG.fillRect(210, 140, 201, 20);
               bG.setColor(inside);
               ix = (int) java.lang.Math.round(201.0 * k / nsteps);
               bG.fillRect(210, 140, ix, 20);
               bG.setColor(wall);
               bG.drawString("Bounces: " + bounces, 216, 185);
               bG.setColor(ball);
               bG.fillRect(210, 110, j, 20);
               for (i = 0; i < nballs; i = i + 1)
               {   
                   ax = bx[i];
                   ay = by[i];
                   cx = bx[i] + vx[i];
                   cy = by[i] + vy[i];
                   bx[i] = cx;
                   by[i] = cy;
                   if (cx * cx + cy * cy > radius * radius)
                      {  
                         mx = (ax + cx)/2;
                         my = (ay + cy)/2;
                         for (j = 0; j < 10; j = j + 1)
                         {     if (mx * mx + my * my < radius * radius)
                               {  ax = mx;
                                  ay = my;
                               }
                               else
                               {  cx = mx;
                                  cy = my;
                               }
                               mx = (ax + cx)/2;
                               my = (ay + cy)/2;
                         }
                         mag = java.lang.Math.sqrt(mx * mx + my * my);
                         sine = my/mag;
                         cosine = mx/mag;
                         tx = cosine * bx[i] + sine * by[i];
                         ty = -sine * bx[i] + cosine * by[i];
                         tx = 2 * radius - tx;
                         bx[i] = cosine * tx - sine * ty;
                         by[i] = sine * tx + cosine * ty;
                         tx = cosine * vx[i] + sine * vy[i];
                         ty = -sine * vx[i] + cosine * vy[i];
                         tx = -tx;
                         vx[i] = cosine * tx - sine * ty;
                         vy[i] = sine * tx + cosine * ty;
                         bounces = bounces + 1;
                         bG.setColor(inside);
                         bG.fillRect(210, 170, 201, 20);
                         bG.setColor(wall);
                         bG.drawString("Bounces: " + bounces, 216, 185);
                         bG.setColor(ball);
                         tx = 100 * java.lang.Math.abs(tx);
                         j = (int) java.lang.Math.round(tx);
                         bG.fillRect(210, 110, j, 20);
                      }           
                   ix = (int) java.lang.Math.round(bx[i]);
                   iy = (int) java.lang.Math.round(by[i]);
                   bG.fillOval(center + ix - 1, center + iy - 1, 3, 3);
               }
               sG.drawImage(bI, 0, 0, this);
            }
            running = 0;
       }

}
             


Copyright c 1995 by Frank Wattenberg Department of Mathematics, Montana State University, Bozeman, MT 59717.