Migration Applet



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

public class Migration extends Applet implements Runnable
{
       Thread       runner;

       Panel         controls1 = new Panel();
       Panel         controls2 = new Panel();
 
       private      TextField PText = new TextField("y", 23);
       private      TextField QText = new TextField("0", 23);

       Expr         Pequation;
       Expr         Qequation;

       int          running = 0;

       Variable     x     = Variable.make("x"); 
       Variable     y     = Variable.make("y");
       Variable     Picon = Variable.make("Pi");
       Variable     PIcon = Variable.make("PI");
       Variable     picon = Variable.make("pi");
       Variable     Econ  = Variable.make("E");
       Variable     econ  = Variable.make("e");

       String       Pfcn  = "y";
       String       Qfcn  = "0";

       Graphics     sG;
       Graphics     bG;
       Image        bI;
       Graphics     cG;
       Image        cI;

       Color        black        = new Color(0, 0, 0);
       Color        white        = new Color(255, 255, 255);
       Color        back         = new Color(247, 243, 234);
       Color        grid         = new Color(128, 128, 255);
       Color        red          = new Color(255, 64, 64);
       Color        green        = new Color(0, 255, 0);

       double       xmin = -1.0;
       double       xmax =  1.0;
       double       ymin = -1.0;
       double       ymax =  1.0;

       double       px, py, fx, fy, max;
       double       hx, hy;
       double       lx, rx, ly, ry;
       double       origx, origy;
       double       sine, cosine;

       int          top    =  80;
       int          width  = 300;
       int          left   =  10;
       int          border =   3;


      public void start()
      {
             if (runner == null)
             {
                runner = new Thread(this);
                runner.start();
             }
      }

      public void run()
      {
      }

      public void init()
      {
              bI = createImage(this.size().width, this.size().height);
              bG = bI.getGraphics();
              cI = createImage(this.size().width, this.size().height);
              cG = cI.getGraphics();
             
              drawback();

              picon.set_value(Math.PI);
              Picon.set_value(Math.PI);
              PIcon.set_value(Math.PI);
              econ.set_value(Math.E);   
              Econ.set_value(Math.E); 

              setBackground(back);
              setFont(new Font("Courier", Font.BOLD, 12));
              controls1.setBackground(back);
              controls1.setFont(new Font("Courier", Font.BOLD, 12));
              controls2.setBackground(back);
              controls2.setFont(new Font("Courier", Font.BOLD, 12));
              controls1.add(new Label(" P(x, y): "));     
              controls1.add(PText);
              controls2.add(new Label(" Q(x, y): "));
              controls2.add(QText);
              add(controls1);
              add(controls2);
       }

       public void paint(Graphics g)
       {
              g.drawImage(cI, 0, top, this);
              sG = getGraphics();
       }

       public void update(Graphics g)
       {
              g.drawImage(cI, 0, top, this);
       }
 
       public void drawback()
       {
              bG.setColor(back);
              bG.fillRect(0, 0, 327, 327); 
              bG.setColor(black);
              bG.fillRect(left, 0, width + 2 * border + 1, width + 2 * border + 1);
              bG.setColor(back); 
              bG.fillRect(left + border, border, width + 1, width + 1);
              bG.setColor(grid);
              for (int i = left + border; i <= left + width + border; i = i + width/10) 
              {
                  bG.drawLine(i, border, i, width + border);
              }
              for (int j = border; j <= width + border ; j = j + width/10)
              {
                  bG.drawLine(left + border, j, left + width + border, j);
              }

              bG.drawLine(left + border + width/2 - 1, border,
                          left + border + width/2 - 1, width + border);
              bG.drawLine(left + border + width/2 + 1, border,
                          left + border + width/2 + 1, width + border);
              bG.drawLine(left + border, border + width/2 - 1,
                          left + border + width, border + width/2 - 1);
              bG.drawLine(left + border, border + width/2 + 1,
                          left + border + width, border + width/2 + 1);

              bG.setColor(red);
              bG.fillOval(left + border + width/2 - 4, 
                          border + width/10 - 4, 9, 9);
              bG.setColor(green);
              bG.fillOval(left + border + width/2 - 4,
                          border + 9 * width / 10 - 4, 9, 9);

              cG.drawImage(bI, 0, 0, this);            
       }

       public boolean mouseDown(Event evt, int mx, int mmy)
       {
              int my;

              my = mmy - top;
              max = 0.0;

              try
              {
                    Pequation = Parser.parse(PText.getText());
              }
              catch (Syntax_error e)
              {
                    System.err.println ("Syntax error: " + e);
              }

              try
              {
                    Qequation = Parser.parse(QText.getText());
              }
              catch (Syntax_error e)
              {
                    System.err.println ("Syntax error: " + e);
              }

              for (px = xmin; px <= xmax; px = px + (xmax - xmin)/30.0)
              {
                  for(py = ymin; py < ymax; py = py + (ymax - ymin)/30.0)
                  {
                       x.set_value(px);
                       y.set_value(py);
                       fx = Pequation.value();
                       fy = Qequation.value();
                       max = java.lang.Math.max(max,
                             java.lang.Math.sqrt(fx * fx + fy * fy)); 
                  }
              }

              px = xmin + (xmax - xmin) * (mx - left - border) / width;
              py = ymax - (ymax - ymin) * (my - border) / width;

              origx = px;
              origy = py;

              lx = px - (xmax - xmin)/15.0;
              rx = px + (xmax - xmin)/15.0;
              ly = py - (ymax - ymin)/15.0;
              ry = py + (ymax - ymin)/15.0;

              x.set_value(px);
              y.set_value(py);
              fx = Pequation.value();
              fy = Qequation.value();

              hx = (xmax - xmin) * fx / (max * 300);
              hy = (ymax - ymin) * fy / (max * 300);

              if(fx * fx + fy * fy == 0)
              {
                  cG.drawImage(bI, 0, 0, this);
                  cG.setColor(black);
                  cG.fillOval(mx - 2, my - 2, 5, 5);
                  sG.drawImage(cI, 0, top, this);
                  return true;
              }
              else
              {
                  sine   = fy/java.lang.Math.sqrt(fx * fx + fy * fy);
                  cosine = fx/java.lang.Math.sqrt(fx * fx + fy * fy);
                  migrate();
                  return true;
              }
       }

       public int xscale(double qx)
       {
              int    ix;
              double tx;
              tx = left + border + width * (qx - xmin) / (xmax - xmin);
              ix = (int) java.lang.Math.round(tx);
              return ix;
       }

       public int yscale(double qy)
       {
              int    iy;
              double ty;
              ty = border + width * (qy - ymax) / (ymin - ymax);
              iy = (int) java.lang.Math.round(ty);
              return iy;
       }

       public void drawbodies()
       {
              double   delta = (xmax - xmin)/ 30;
              double   qx, qy;

              cG.drawImage(bI, 0, 0, this);
              cG.setColor(black);

              for (double dx = -2.0 * delta; dx < .01 * delta; dx = dx + delta)
              {
                  for (double dy = -delta; dy < 1.01 * delta; dy = dy + delta)
                  {
                      qx = px + cosine * dx - sine * dy;
                      qy = py + sine * dx + cosine * dy;
                      cG.fillOval(xscale(qx) - 1, yscale(qy) - 1, 3, 3);
                  }
              }
              sG.drawImage(cI, 0, top, this);
       }

       public void migrate()
       {
              running = 1;
              drawbodies();
       
              for (int n = 0; n < 150; n = n + 1)
              {
                  try 
                  {   runner.sleep(20);
                  }
                  catch(InterruptedException e) {};

                  px = px + hx;
                  py = py + hy;

                  if ((px < lx) || (px > rx) || (py < ly) || (py > ry))
                  {
                       px = origx;
                       py = origy;
                  }

                  drawbodies();
              }

              cG.drawImage(bI, 0, 0, this);
              sG.drawImage(cI, 0, top, this);
                        
              running = 0;
      }
}


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