import java.awt.*; import java.applet.*; import java.lang.*; import java.lang.Number; import java.lang.Math; /** * Draws a clock with the specified modulus. * Labels it with representatives for congruence classes in one or more cycles * Some of the things in this applet work, but are not used. */ public class clock extends Applet { clockControls controls; public void init() { setLayout(new BorderLayout()); clockCanvas c = new clockCanvas(); add("Center", c); add("South", controls = new clockControls(c)); } public void start() { controls.enable(); } public void stop() { controls.disable(); } public boolean handleEvent(Event e) { if (e.id == Event.WINDOW_DESTROY) { System.exit(0); } return false; } public static void main(String args[]) { Frame f = new Frame("clock"); clock clock = new clock(); clock.init(); clock.start(); f.add("Center", clock); f.resize(300, 300); f.show(); } } class clockCanvas extends Canvas { int modulus = 12; int cycles = 1; int firstCycle = 0; int hand = 0; int term1 = 0; int term2 = 0; public void paint(Graphics g) { Point endHand = new Point(xcoord(80,resAngle(this.hand)), ycoord(80,resAngle(this.hand))); g.translate(200,200); g.setColor(Color.white); g.fillOval(-100,-100,200,200); g.setColor(Color.black); g.drawOval(-100,-100,200,200); /*PtoR(endHand, 80, resAngle(hand));*/ g.setColor(Color.red); g.drawLine(0,0,endHand.x, endHand.y); drawArrowhead(g,endHand.x, endHand.y,resAngle(hand)); g.setColor(Color.green); drawArrowArc(g,0,term1); g.setColor(Color.black); for (int i = 0; i < modulus; i++) { g.drawLine( xcoord(100,resAngle(i)), ycoord(100,resAngle(i)), xcoord(95,resAngle(i)), ycoord(95,resAngle(i))); } g.translate(-5,4); for (int j = firstCycle; j < cycles; j++) { for (int i = 0; i < modulus; i++) { g.drawString( Integer.toString(j*modulus+i), xcoord(90+20*j,resAngle(j*modulus+i)), ycoord(90+20*j,resAngle(j*modulus+i))); } } } /* Conversion from polar coordinates to rectangular */ public int xcoord(int r, double theta) { int x = (int)((double)r * Math.cos(-theta * Math.PI / 180)); return x; } public int ycoord(int r, double theta) { int y = (int)((double)r * Math.sin(-theta * Math.PI / 180)); return y; } /*Screen angle on a clock corresponding to a residue with respect to the modulus. * Clock angles go clockwise and start at top. Screen angles go counterclockwise and start at 3 oclock. */ public double resAngle(int res) { double theta = (double)(90-360*res/modulus); return theta; } public void drawArrowhead(Graphics g, int x, int y, double theta) { g.translate(x,y); g.drawLine(0,0,xcoord(10,theta+180+30),ycoord(10,theta+180+30)); g.drawLine(0,0,xcoord(10,theta+180-30),ycoord(10,theta+180-30)); g.translate(-x,-y); } public void drawArrowArc(Graphics g, int a, int b) { if (b-a != 0) { g.drawArc(-110,-110,220,220,(int)(resAngle(a)),(int)(-(b-a)*360/modulus)); drawArrowhead(g,xcoord(110,resAngle(b)), ycoord(110,resAngle(b)), resAngle(b)-(Math.abs(b-a)/(b-a))*90); } } public void redraw(int a, int b) { { this.hand++; this.term1 = a; this.term2 = b; repaint(); } } } class clockControls extends Panel { TextField n1; TextField n2; clockCanvas canvas; Thread tickerthread; public clockControls(clockCanvas canvas) { this.canvas = canvas; add(new Button("Tick")); add(new Button("Stop")); } public boolean action(Event ev, Object arg) { if (ev.target instanceof Button) { String buttonLabel = (String)arg; if (buttonLabel.equals("Tick")) { if (tickerthread == null) { tickerthread = new Thread(new ticker(1000, this.canvas)); tickerthread.start(); } } else if (buttonLabel.equals("Stop")) { if (tickerthread != null) { tickerthread.stop(); tickerthread = null; } } return true; } return false; } } class ticker implements Runnable { int interval; clockCanvas myclock; ticker(int interval, clockCanvas myclock) { this.interval = interval; this.myclock = myclock; } public void run() { while(true) { try { Thread.sleep(interval); myclock.redraw(0, 0); } catch (Exception e) return; } } }