import java.net.URL; import java.io.*; import java.awt.*; import java.lang.Math; import java.util.Random; import java.util.Date; import java.net.MalformedURLException; public class WormWatchApplet extends java.applet.Applet { public int W = 750; public int H = 750; public int nquakes = 0; public int MAX_QUAKES = 100; public final Color bg = Color.white; boolean threadSuspended = false; Image im; Image mapImage; Graphics offscreen; WormClock wormclock; WormWaves wormwaves; QuakeChecker quakechecker; Quake quakes[] = new Quake[MAX_QUAKES]; public void init() { mapImage = getImage(getCodeBase(),"cities_color.gif"); resize(W, H); try { im = createImage(W, H); offscreen = im.getGraphics(); } catch (Exception e) { offscreen = null; } } /* Start the threads for each part of the applet */ public void start() { if (wormclock == null) { wormclock = new WormClock(this); wormclock.start(); try { quakechecker = new QuakeChecker(this); } catch (Exception e) {} } if (wormwaves == null) { wormwaves = new WormWaves(this); wormwaves.start(); } repaint(); } public void addquake(Quake q) { quakes[nquakes++] = q; } /* when applet is stopped, stop individual threads */ public void stop() { wormclock.stop(); wormwaves.stop(); } /* override the update method to reduce flashing */ public void update(Graphics g) { paint(g); } /* Use double buffering to reduce flashing */ public void paint(Graphics g) { if (offscreen != null) { paintApplet(offscreen); g.drawImage(im,0,0,this); } else { paintApplet(g); } } /* call each thing's paint method */ public void paintApplet(Graphics g) { boolean changed = false; g.setColor(bg); g.fillRect(0, 0, W, H); g.drawImage(mapImage,0,0,this); wormclock.paint(g); try { wormwaves.paint(g); } catch(java.lang.NullPointerException e) { System.out.println("waves.paint barfs: " + e.getMessage()); } for(int i=0;i 0) { quakes[nquakes-1].describe(g); quakes[nquakes-1].highlight(g); } } /* on mouse activity, make a mess of some sort */ public boolean mouseDown(Event e, int x, int y) { System.out.println("Mouse down at " + x + ", " + y); return(true); } public boolean mouseUp(Event e, int x, int y) { return(true); } } /* * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. Please refer to the file "copyright.html" * for further important copyright and licensing information. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ class WormClock implements Runnable { public Thread timer = null; public boolean changed = true; int lastxs=0, lastys=0, lastxm=0, lastym=0, lastxh=0, lastyh=0; Date dummy = new Date(); // String lastdate = dummy.toLocaleString(); String lastdate = dummy.toGMTString(); WormWatchApplet applet; public WormClock(WormWatchApplet applet) { this.applet = applet; } // Plotpoints allows calculation to only cover 45 degrees of the circle, // and then mirror public void plotpoints(int x0, int y0, int x, int y, Graphics g) { g.drawLine(x0+x,y0+y,x0+x,y0+y); g.drawLine(x0+y,y0+x,x0+y,y0+x); g.drawLine(x0+y,y0-x,x0+y,y0-x); g.drawLine(x0+x,y0-y,x0+x,y0-y); g.drawLine(x0-x,y0-y,x0-x,y0-y); g.drawLine(x0-y,y0-x,x0-y,y0-x); g.drawLine(x0-y,y0+x,x0-y,y0+x); g.drawLine(x0-x,y0+y,x0-x,y0+y); } // Circle is just Bresenham's algorithm for a scan converted circle public void circle(int x0, int y0, int r, Graphics g) { int x,y; float d; x=0; y=r; d=5/4-r; plotpoints(x0,y0,x,y,g); while (y>x){ if (d<0) { d=d+2*x+3; x++; } else { d=d+2*(x-y)+5; x++; y--; } plotpoints(x0,y0,x,y,g); } } // Paint is the main part of the program public void paint(Graphics g) { int xh, yh, xm, ym, xs, ys, s, m, h, xcenter, ycenter; String today; Date dat = new Date(); s = dat.getSeconds(); m = dat.getMinutes(); h = dat.getHours(); h += dat.getTimezoneOffset()/60; while(h > 12) h -= 12; // today = dat.toLocaleString(); today = dat.toGMTString(); xcenter=532; ycenter=43; // a= s* pi/2 - pi/2 (to switch 0,0 from 3:00 to 12:00) // x = r(cos a) + xcenter, y = r(sin a) + ycenter xs = (int)(Math.cos(s * 3.14f/30 - 3.14f/2) * 33 + xcenter); ys = (int)(Math.sin(s * 3.14f/30 - 3.14f/2) * 33 + ycenter); xm = (int)(Math.cos(m * 3.14f/30 - 3.14f/2) * 28 + xcenter); ym = (int)(Math.sin(m * 3.14f/30 - 3.14f/2) * 28 + ycenter); xh = (int)(Math.cos((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 18 + xcenter); yh = (int)(Math.sin((h*30 + m/2) * 3.14f/180 - 3.14f/2) * 18 + ycenter); // Draw the circle and numbers g.setFont(new Font("TimesRoman", Font.PLAIN, 12)); g.setColor(Color.black); circle(xcenter,ycenter,38,g); g.setColor(Color.black); g.drawString("9",xcenter-33,ycenter+3); g.drawString("3",xcenter+28,ycenter+3); g.drawString("12",xcenter-5,ycenter-25); g.drawString("6",xcenter-3,ycenter+33); // Erase if necessary, and redraw g.setColor(Color.white); if (xs != lastxs || ys != lastys) { g.drawLine(xcenter, ycenter, lastxs, lastys); g.drawString(lastdate, xcenter - 70, ycenter + 48 ); } if (xm != lastxm || ym != lastym) { g.drawLine(xcenter, ycenter-1, lastxm, lastym); g.drawLine(xcenter-1, ycenter, lastxm, lastym); } if (xh != lastxh || yh != lastyh) { g.drawLine(xcenter, ycenter-1, lastxh, lastyh); g.drawLine(xcenter-1, ycenter, lastxh, lastyh); } g.setColor(Color.black); g.drawString(today, xcenter - 70, ycenter + 48); g.drawLine(xcenter, ycenter, xs, ys); g.setColor(Color.black); g.drawLine(xcenter, ycenter-1, xm, ym); g.drawLine(xcenter-1, ycenter, xm, ym); g.drawLine(xcenter, ycenter-1, xh, yh); g.drawLine(xcenter-1, ycenter, xh, yh); lastxs=xs; lastys=ys; lastxm=xm; lastym=ym; lastxh=xh; lastyh=yh; lastdate = today; } public void start() { if(timer == null) { timer = new Thread(this,"Clock"); timer.start(); } } public void stop() { timer = null; } public void run() { while (timer != null) { changed = true; applet.repaint(); try {Thread.sleep(100);} catch (InterruptedException e){} } timer = null; } public void update(Graphics g) { paint(g); } } class Quake { int orid; Location loc; double depth; double time; double mag; int nph; static int splatrad = 10; Quake(int an_orid,double a_lat,double a_lon,double a_depth, double a_time, double a_mag, int some_ph) { orid = an_orid; this.loc = new Location(a_lat,a_lon); depth = a_depth; time = a_time; mag = a_mag; nph = some_ph; } public void plotpoints(int x0, int y0, int x, int y, Graphics g) { g.drawLine(x0+x,y0+y,x0+x,y0+y); g.drawLine(x0+y,y0+x,x0+y,y0+x); g.drawLine(x0+y,y0-x,x0+y,y0-x); g.drawLine(x0+x,y0-y,x0+x,y0-y); g.drawLine(x0-x,y0-y,x0-x,y0-y); g.drawLine(x0-y,y0-x,x0-y,y0-x); g.drawLine(x0-y,y0+x,x0-y,y0+x); g.drawLine(x0-x,y0+y,x0-x,y0+y); } public void circle(int x0, int y0, int r, Graphics g) { int x,y; float d; x=0; y=r; d=5/4-r; plotpoints(x0,y0,x,y,g); while (y>x){ if (d<0) { d=d+2*x+3; x++; } else { d=d+2*(x-y)+5; x++; y--; } plotpoints(x0,y0,x,y,g); } } public void describe(Graphics g) { Date epoch = new Date(); epoch.setTime((long) (this.time * 1000)); g.setFont(new Font("TimesRoman",Font.PLAIN,12)); g.drawString("Time " + epoch.toGMTString(),30,10); g.drawString("Lat " + this.loc.lat,30,25); g.drawString("Lon " + this.loc.lon,30,40); g.drawString("Depth " + this.depth,30,55); g.drawString("Ndef " + this.nph,30,70); g.drawString("Ml " + this.mag,30,85); } public void highlight(Graphics g) { PixelCoord pc; pc = this.loc.pix(); g.setColor(Color.blue); circle(pc.x,pc.y,15,g); g.setColor(Color.black); } public boolean inside(int x, int y) { double xdist,ydist,dist; PixelCoord pc; pc = this.loc.pix(); xdist = (double) (x - pc.x); ydist = (double) (y - pc.y); dist = Math.sqrt(xdist*xdist+ydist*ydist); if((int) dist <= splatrad) { return(true); } else { return(false); } } public void splat(Graphics g) { PixelCoord pc; pc = this.loc.pix(); g.setFont(new Font("TimesRoman",Font.PLAIN,14)); g.setColor(Color.blue); circle(pc.x,pc.y,splatrad,g); g.setColor(Color.black); g.drawString(Integer.toString(this.nph),pc.x - 5,pc.y + 5); // g.setColor(Color.red); // g.drawString(Integer.toString(pc.x),pc.x + 25,pc.y + 5); // g.drawString(Integer.toString(pc.y),pc.x + 55,pc.y + 5); // g.setColor(Color.black); } } class PixelCoord { int x; int y; PixelCoord(int an_x,int a_y) { x = an_x; y = a_y; } } class Location { double lat; double lon; static int MapXCtr = 300; static int MapYCtr = 356; static int PixPerDeg = 52; static double MapLatCtr = 62.4047; static double MapLonCtr = -150.2695; Location(double a_lat, double a_lon) { lat = a_lat; lon = a_lon; }; public PixelCoord latlon2pix(Location loc) { int x; int y; double lat; double lon; double xdist,ydist; double dist; double az; double pixdist; lat = loc.lat; lon = loc.lon; ydist = lat - MapLatCtr; xdist = lon - MapLonCtr; az = Math.atan(ydist / xdist); if(xdist<0.) az += Math.PI; dist = Math.sqrt(xdist*xdist+ydist*ydist); pixdist = dist * PixPerDeg; x = (int) (MapXCtr + pixdist*Math.cos(az)); y = (int) (MapYCtr - pixdist*Math.sin(az)); return new PixelCoord(x,y); } PixelCoord pix() { return latlon2pix(this); } } class QuakeChecker { int x = 0; double lat = 0; double lon = 0; double depth = 0; double time = 0; long jdate = 0; int orid = 0, evid = 0; int nass = 0, ndef = 0; double ml = 0; Quake q; // File f; // FileInputStream fs; URL u; InputStream is; StreamTokenizer st; WormWatchApplet applet; public QuakeChecker(WormWatchApplet applet) throws java.io.IOException { this.applet = applet; // f = new File("/usr/local/EarthWorm/v2.0.k/run_MOMENT/Quakes_960124.origin"); // fs = new FileInputStream(f); // st = new StreamTokenizer(fs); u = new URL("http://enigma.unr.edu/JavaWorm/origin.html"); is = u.openStream(); st = new StreamTokenizer(is); st.eolIsSignificant(true); st.commentChar('#'); st.nextToken(); while(st.ttype != StreamTokenizer.TT_EOF) { lat = st.nval; st.nextToken(); lon = st.nval; st.nextToken(); depth = st.nval; st.nextToken(); time = st.nval; st.nextToken(); orid = (int) st.nval; st.nextToken(); evid = (int) st.nval; st.nextToken(); jdate = (long) st.nval; st.nextToken(); nass = (int) st.nval; st.nextToken(); ndef = (int) st.nval; st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); st.nextToken(); ml = st.nval; while(st.nextToken() != StreamTokenizer.TT_EOL); st.nextToken(); q = new Quake(orid,lat,lon,depth,time,ml,ndef); applet.addquake(q); System.out.println("orid " + orid + " lat " + lat + " lon " + lon + " depth " + depth + " ml " + ml); } } } class WormWaves implements Runnable { public Thread wavethread = null; public boolean changed = true; public int wavex = 569; // public int wavey = 700; public int wavey = 250; public int xlen = 180; public int ycurrent[]; URL u; InputStream is; DataInputStream dis; WormWatchApplet applet; public WormWaves(WormWatchApplet applet) { this.applet = applet; try { u = new URL("http://enigma.unr.edu/JavaWorm/waves.html"); } catch (java.net.MalformedURLException e) { } try { is = u.openStream(); } catch (java.io.IOException e) {} dis = new DataInputStream(is); ycurrent = new int[xlen + 1]; for(int i = 0; i < xlen + 1; i++) { ycurrent[i] = 0; } } public void paint(Graphics g) { g.setColor(Color.black); for(int x = 0; x < xlen; x++) { g.drawLine(x + wavex,ycurrent[x] + wavey, x + wavex + 1, ycurrent[x+1] + wavey); ycurrent[x] = ycurrent[x+1]; } } public void start() { if(wavethread == null) { wavethread = new Thread(this,"Waves"); wavethread.start(); } } public void stop() { wavethread = null; } public void run() { while (wavethread != null) { changed = true; try { ycurrent[xlen] = (int) dis.readShort(); ycurrent[xlen] /= 10; // System.out.println("Number is " + // Integer.toString(ycurrent[xlen])); } catch (java.io.IOException e) {} applet.repaint(); try {Thread.sleep(100);} catch (InterruptedException e){} } wavethread = null; } public void update(Graphics g) { paint(g); } }