home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / LANGUAGE / JAVA / NOTES / SOURCE / trackln.jav < prev    next >
Text File  |  1996-12-20  |  9KB  |  244 lines

  1.  
  2. /*
  3.    This applet shows short line segments arranged into regular rows and
  4.    columns.  One end of each line if fixed, and the line can rotate around
  5.    that endpoint.  The lines rotate at randomly selected speeds, unless
  6.    the mouse moves over the applet.  Then all the lines point at the
  7.    mouse.  But if the mouse doesn't move for a while, the lines start
  8.    drifting again.  Furthermore, if the mouse button is pressed, then
  9.    the color of the lines changes.  The color depends on the exact mouse
  10.    position.
  11.    
  12.    David Eck, August 21, 1996
  13.    eck@hws.edu
  14. */
  15.  
  16.  
  17. import java.awt.*;
  18. import java.applet.*;
  19.  
  20. public class TrackLines extends Applet implements Runnable {
  21.  
  22.    boolean used = false; // Set to true the first time the lines
  23.                          //    point at the mouse; until then, a
  24.                          //    message is also displayed.
  25.  
  26.    int ROWS = 5;     // how many rows of lines; can be set as an applet parameter
  27.    int COLUMNS = 7;  // how many columns; can be set as an applet parameter
  28.  
  29.    int[][] angle;       // current angle of each line, in degrees
  30.    int[][] driftSpeed;  // current rotation speed of each line, in degrees per frame
  31.  
  32.    Color color = Color.black;   // color in which lines are displayed
  33.    long lastTime = 0;   // the time when the lines last pointed at the mouse (milliseconds)
  34.    int delayToDrift  = 1500;    // how long will lines point at same spot before drifting
  35.                                 //        (in milliseconds)
  36.    
  37.    int width = -1;   // actual width of the applet (initially unknown; set in doResize())
  38.    int height = -1;  // actual height of the applet
  39.    int hSpace;  // horizontal space between lines ( = width / COLUMNS)
  40.    int vSpace;  // vertical space between lines ( = height / ROWS)
  41.    int space;   // length of each line ( = min(hSpace,vSpace) / 2)
  42.  
  43.    int last_x = -1;  // the lines were most recently pointed at (last_x, last_y)
  44.    int last_y = -1;
  45.  
  46.    int sleepTime = 100;   // delay between frames when lines are drifting
  47.  
  48.    Thread runner = null;   // Thread for doing the drifing animation
  49.    Image OSC = null;       // Off-screen canvas for double buffering, created in doResize()
  50.    Graphics OSCGraphics;   // Graphics context for OSC
  51.    
  52.    
  53.    public void init() {
  54.       setBackground(Color.white);
  55.       String param;
  56.       param = getParameter("rows");                  // get the parameters
  57.       if (param != null) {
  58.          try {
  59.             ROWS = Integer.parseInt(param);
  60.           }
  61.           catch (NumberFormatException e) { }
  62.       }
  63.       param = getParameter("columns");
  64.       if (param != null) {
  65.          try {
  66.             COLUMNS = Integer.parseInt(param);
  67.           }
  68.           catch (NumberFormatException e) { }
  69.       }
  70.       angle = new int[ROWS][COLUMNS];              // set up random initial angles and driftspeeds
  71.       driftSpeed = new int[ROWS][COLUMNS];
  72.       for (int i = 0; i<ROWS; i++)
  73.          for (int j=0; j<COLUMNS; j++) {
  74.             angle[i][j] = (int)(360*Math.random());
  75.             driftSpeed[i][j] = (int)(41*Math.random()) - 20;
  76.          }
  77.    }
  78.    
  79.    public void start() {
  80.              // check values of height,width and start a thread to do the animation
  81.       if (runner == null) {
  82.          int h = size().height;
  83.          int w = size().width;
  84.          if (h != height || w != width)
  85.             doResize(w,h);
  86.          runner = new Thread(this);
  87.          runner.start();
  88.       }
  89.    }
  90.    
  91.    public void stop() {
  92.             // stop the animation
  93.       if (runner != null) {
  94.          runner.stop();
  95.          runner = null;
  96.       }
  97.    }
  98.    
  99.  
  100.    synchronized public void paint(Graphics g) {
  101.              // just copy the offscreen canvas to the screen
  102.       if (OSC != null) {
  103.          g.drawImage(OSC,0,0,this);
  104.       }
  105.    }
  106.    
  107.    public void update(Graphics g) {
  108.              // override update(), so that it doesn't erase before calling paint()
  109.       paint(g);
  110.    }
  111.    
  112.    void doResize(int w, int h) {
  113.             // applet has changed size to w-by-h; get a new off-screen canvas of
  114.             // the same size, and calculate some size parameters
  115.       OSC = null;
  116.       OSC = createImage(w,h);
  117.       OSCGraphics = OSC.getGraphics();
  118.       width = w;
  119.       height = h;
  120.       hSpace = (width + 2) / (COLUMNS);
  121.       vSpace = (height + 2) / (ROWS);
  122.       space = (hSpace < vSpace) ? hSpace/2 : vSpace/2;
  123.    }
  124.    
  125.    synchronized void drift() {
  126.             // all the lines rotate a bit, but this is only done if
  127.             // its been at least delayToDrift milliseconds since the
  128.             // last time the lines pointed at the mouse
  129.       if (System.currentTimeMillis() - lastTime < delayToDrift)
  130.          return;
  131.       int w = size().width;
  132.       int h = size().height;
  133.       if (w != width || h != height)
  134.          doResize(w,h);
  135.       OSCGraphics.setColor(Color.white);
  136.       OSCGraphics.fillRect(0,0,w,h);
  137.       OSCGraphics.setColor(color);
  138.       for (int i=0; i<ROWS; i++)
  139.          for (int j=0; j<COLUMNS; j++) {
  140.             angle[i][j] += driftSpeed[i][j];  // rotate the line a bit
  141.             if (Math.random() < 0.05)  // a 1 out of 20 chance that drift speed changes
  142.                driftSpeed[i][j] = (int)(41*Math.random()) - 20;
  143.             int x = j*hSpace + space;  // fixed endpoint of line
  144.             int y = i*vSpace + space;
  145.             int x1 = x + (int)(space*Math.cos((Math.PI/180.0)*angle[i][j]));  // other endpoint
  146.             int y1 = y + (int)(space*Math.sin((Math.PI/180.0)*angle[i][j]));
  147.             OSCGraphics.drawLine(x,y,x1,y1);
  148.          }
  149.       if (!used)
  150.          putMessage();
  151.       repaint();  // arrange for screen updating
  152.    }
  153.    
  154.    synchronized void point(int x1, int y1) {
  155.             // all the lines point at (x1,y1)
  156.       if (last_x == x1 && last_y == y1)
  157.          return;  // if they are already pointing there, there's nothing to do
  158.       int w = size().width;
  159.       int h = size().height;
  160.       if (w != width || h != height)
  161.          doResize(w,h);
  162.       OSCGraphics.setColor(Color.white);
  163.       OSCGraphics.fillRect(0,0,w,h);
  164.       OSCGraphics.setColor(color);
  165.       for (int i=0; i<ROWS; i++)
  166.          for (int j=0; j<COLUMNS; j++) {
  167.             int x = j*hSpace + space;  // fixed endpoint of line
  168.             int y = i*vSpace + space;
  169.             int dx = x1 - x;  // (dx,dy) is a vector pointing in the right direction
  170.             int dy = y1 - y;
  171.             if (dx != 0 || dy != 0) {              
  172.                double angl = Math.atan2(dy,dx);   // computes angle of vector (dx,dy)
  173.                angle[i][j] = (int)(angl*180.0/Math.PI);
  174.                int x2 = x + (int)(space*Math.cos((Math.PI/180.0)*angle[i][j]));   // other endpoint
  175.                int y2 = y + (int)(space*Math.sin((Math.PI/180.0)*angle[i][j]));
  176.                OSCGraphics.drawLine(x,y,x2,y2);
  177.             }
  178.          }
  179.       last_x = x1;   // save info about this event
  180.       last_y = y1;
  181.       lastTime = System.currentTimeMillis();
  182.       repaint();  // arrange for screen updating
  183.    }
  184.    
  185.    synchronized void selectColor(int x, int y) {
  186.            // change the drawing color, depending on the value of x and y.
  187.            // x gives the hue of the color, ranging from violet to red.
  188.            // y gives the brightness, ranging from 0.3 to 1.0
  189.       if (x < 0)
  190.          x = 0;
  191.       else if (x > width)
  192.          x = width;
  193.       if (y < 0)
  194.          y = 0;
  195.       else if (y > height)
  196.          y = height;
  197.       float hue = ((float)(width-x)) / ((float)width);
  198.       float bright = 0.3F + 0.7F*((float)(height-y)) / ((float)height);
  199.       color = Color.getHSBColor(hue,1.0F,bright);
  200.    }
  201.    
  202.    void putMessage() {
  203.           // This message is displayed until the mouse moves over the applet
  204.       if (OSC == null)
  205.          return;
  206.       OSCGraphics.setColor(Color.red);
  207.       OSCGraphics.drawString("Point your mouse at me!", 25, 40);
  208.       OSCGraphics.drawString("Click on me!", 25, 80);
  209.    }
  210.    
  211.    public boolean mouseMove(Event evt, int x, int y) {
  212.           // point at the mouse each time it moves
  213.       used = true;
  214.       point(x,y);
  215.       return true;
  216.    }   
  217.    
  218.    public boolean mouseDown(Event evt, int x, int y) {
  219.           // point at the mouse and select a color based on its position
  220.