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

public class Realistic extends Applet
{
      Graphics      bG;
      Graphics      sG;
      Graphics      cG;
      Image         bI;
      Image         cI;

      Color         back         = new Color(247, 243, 234);
      Color         cobback      = new Color(192, 255, 192);
      Color         coblines     = new Color(0, 255, 0);
      Color         timeback     = new Color(192, 192, 255);
      Color         timelines    = new Color(0, 0, 255);
      Color         function     = new Color(255, 0, 0);
      Color         diagonal     = new Color(0, 0, 0);
      Color         ameter       = new Color(255, 192, 192);
      Color         black        = new Color(0, 0, 0);
      Color         splinelines  = new Color(128, 64, 0);
      Color         splineback   = new Color(255, 196, 128);
      Color         red          = new Color(255, 0, 0);

      double        x, y, ox, oy, px, py;
      double        C = 1000;
      double        a = 1.0;
      double        start = 50.0;
      double[]      pts = {1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2,
                           1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2,
                           1.2, 1.0, 0.8, 0.6, 0.4, 0.2, 0.0}; 

      int           n = 40;
      int           ok;
      int           k;
      int           sw = 1;
      int           nsw;
      int           ipt;

      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();
             ox = start;
             oy = start;
             ok = 0;
             drawback();
      }

      public void paint(Graphics g)
      {
             if (sw == 0) g.drawImage(bI, 0, 0, this);
             if (sw == 1) g.drawImage(cI, 0, 0, this);
             sG = getGraphics();
      }

      public void update(Graphics g)
      {
             if (sw == 0) g.drawImage(bI, 0, 0, this);
             if (sw == 1) g.drawImage(cI, 0, 0, this);
      }


       public int cyscale(double z)
       {
              int iy;
              iy = (int) java.lang.Math.round(205 - 200 * z / C);
              return iy;
       }

       public int cxscale(double z)
       {
              int ix;
              ix = (int) java.lang.Math.round(5 + 200 * z / C);
              return ix;
       }

       public int txscale(int z)
       {
              int ix;
              ix = (int) (215 + java.lang.Math.round(z * 200.0 / n));
              return ix;
       }

       public int ascale(double z)
       {
              int ix;
              ix = (int) (110 + java.lang.Math.round((a - 0.5) * 200));
              return ix;
       }

       public int syscale(double z)
       {
              int ix;
              ix = (int) (210 - java.lang.Math.round(100 * z));
              return ix;
       }

       public double foo(double p)
       {
              int       j;
              double    t;
              double    pout = 0.0;
              j = (int) java.lang.Math.floor(p/50.0);
              if (j < 20)
              {
                 t = (p - (j * 50.0))/50.0;
                 pout = a * p * ((1 - t) * pts[j] + t * pts[j + 1]);
              }
              if (j == 20) pout = a * p * pts[20];
              pout = java.lang.Math.max(0, pout);
              return pout;
       }

public void thickline(int a, int b, int c, int d, Graphics g)
       {
              g.drawLine(a, b, c, d);
              g.drawLine(a + 1, b, c + 1, d);
              g.drawLine(a - 1, b, c - 1, d);
              g.drawLine(a, b + 1, c, d + 1);
              g.drawLine(a, b - 1, c, d - 1);

       }

       public void drawback()
       {
              bG.setColor(back);
              bG.fillRect(0, 0, 421, 251);
              bG.setColor(cobback);
              bG.fillRect(5, 5, 201, 201);
              bG.setColor(timeback);
              bG.fillRect(215, 5, 201, 201);
              bG.setColor(coblines);
              for (int iy = 5; iy < 206; iy = iy + 20)
              {
                  bG.drawLine(5, iy, 205, iy);
                  bG.drawLine(iy, 5, iy, 205);
              }
              bG.setColor(timelines);
              for (int iy = 5; iy < 206; iy = iy + 20)
              {
                  bG.drawLine(215, iy, 415, iy);
              }
              for (int iy = 0; iy < n + 1; iy = iy + 10)
              {
                  bG.drawLine(txscale(iy), 5, txscale(iy), 205);
              }

              bG.setColor(diagonal);
              bG.drawLine(5, 205, 205, 5);
              bG.setColor(function);
              px = 0;
              py = foo(0);
              for (int i = 1; i < 201; i = i + 1)
              {
                   x = px + C / 200.0;
                   y = foo(x);
                   bG.drawLine(cxscale(px), cyscale(py), cxscale(x), cyscale(y));
                   px = x;
                   py = y;
              }
              bG.setColor(black);
              bG.fillOval(txscale(0) - 2, cyscale(start) - 2, 5, 5);
              bG.fillOval(cxscale(start) - 2, cyscale(0) - 2, 5, 5);
              bG.drawLine(cxscale(start), cyscale(0), cxscale(start), cyscale(start));
              bG.setColor(splinelines);
              bG.fillRect(5, 215, 411, 31);
              bG.setColor(splineback);
              bG.fillRect(8, 218, 405, 25);
              cG.setColor(back);
              cG.fillRect(0, 0, 421, 251);
              cG.setColor(splineback);
              cG.fillRect(10, 10, 401, 201);
              cG.setColor(splinelines);
              for (int iy = 10; iy < 411; iy = iy + 20)
              {
                  cG.drawLine(iy, 10, iy, 210);
              }
              for (int iy = 10; iy < 211; iy = iy + 10)
              {   
                  cG.drawLine(10, iy, 410, iy);
              }
              cG.setColor(red);
              cG.drawLine(10, syscale(1)-1, 410, syscale(1)-1); 
              cG.drawLine(10, syscale(1), 410, syscale(1)); 
              cG.drawLine(10, syscale(1)+1, 410, syscale(1)+1); 
              cG.setColor(timelines);
              cG.fillRect(10, 215, 401, 31);
              cG.setColor(timeback);
              cG.fillRect(13, 218, 395, 25);
              cG.setColor(black);
              for (int j = 0; j < 21; j = j + 1)
              {
                  cG.fillOval(9 + j * 20 - 1, syscale(pts[j]) - 2, 5, 5);
              }
              for (int j = 0; j < 20; j = j + 1)
              {
                  thickline(10 + j * 20, syscale(pts[j]),
                              30 + j * 20, syscale(pts[j+1]), cG);
              }
      }

      public boolean mouseDown(Event evt, int mx, int my)
      {
             nsw = sw;
             if  ((sw == 0) && (my < 190))
             {   
                 k = ok + 1;
                 x = foo(ox);
                 y = x;
                 bG.setColor(black);
                 bG.drawLine(cxscale(ox), cyscale(oy), cxscale(ox), cyscale(y));
                 bG.drawLine(cxscale(ox), cyscale(y), cxscale(x), cyscale(y));
                 bG.fillOval(cxscale(ox) - 1, cyscale(y) - 1, 3, 3);
                 if  (k < n + 1)
                 {
                     bG.drawLine(txscale(ok), cyscale(oy), txscale(k), cyscale(y));
                     bG.fillOval(txscale(k) - 1, cyscale(y) - 1, 3, 3);
                 }
                 ok = k;
                 ox = x;
                 oy = y;
                 sG.drawImage(bI, 0, 0, this);
            } 
            if ((sw == 0) && (java.lang.Math.abs(my - cyscale(0)) < 10))
            {
                 mx = java.lang.Math.max(mx, 5);
                 mx = java.lang.Math.min(mx, 205);
                 start = C * (mx - 5.0)/200.0;
                 ox = start;
                 oy = start;
                 ok = 0;
                 drawback();
                 sG.drawImage(bI, 0, 0, this);
            }
            if  ((sw == 0) && (my > 215))
            {
                 nsw = 1;
                 sG.drawImage(cI, 0, 0, this);
            }
            if  ((sw == 1) && (my > 215))
            {
                 nsw = 0;
                 sG.drawImage(bI, 0, 0, this);
            }
            if ((sw == 1) && (my < 212))
            {
                 ipt = mx/20;
                 ipt = java.lang.Math.max(0, ipt);
                 ipt = java.lang.Math.min(20, ipt);
                 my = java.lang.Math.max(10,  my);
                 my = java.lang.Math.min(210, my);
                 pts[ipt] = (210.0 - my)/100.0;
                 a = 1.0;
                 ox = start;
                 oy = start;
                 ok = 0;
                 drawback();
                 sG.drawImage(cI, 0, 0, this);
            }
            sw = nsw;
            return true;  
      }

}
                              


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