import java.awt.*; import java.applet.*; import java.lang.Math; /** * An interactive test of the Graphics.drawArc and Graphics.fillArc * routines. Can be run either as a standalone application by * typing "java Spirograph" or as an applet in the AppletViewer. */ public class Spirograph extends Applet { SpiroControls controls; public void init() { setLayout(new BorderLayout()); SpiroCanvas c = new SpiroCanvas(); add("Center", c); add("South", controls = new SpiroControls(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("Spirograph"); Spirograph spiro = new Spirograph(); spiro.init(); spiro.start(); f.add("Center", spiro); f.resize(300, 300); f.show(); } } class SpiroCanvas extends Canvas { double outside = 120; double inside = 40; double penpos = 0.9; Font font; public void paint(Graphics g) { Rectangle r = bounds(); double itheta = 0; double otheta = 0; double ratio = (1.0*outside)/inside; double orad = Math.min(r.height/2.0, r.width/2.0); double irad = orad/ratio; int centerx = r.width/2; int centery = r.height/2; int oldx = -100; int oldy = -100; int startx = 0, starty = 0; int x,y; boolean canQuit = false; double delta=0.05; g.setColor(Color.black); for (otheta=0.0; otheta < 1000.0; otheta+=0.05 ) { itheta = -otheta*ratio; x = centerx+(int)(Math.cos(otheta)*(orad-irad) + Math.cos(otheta+itheta)*irad*penpos); y = centery+(int)(Math.sin(otheta)*(orad-irad) + Math.sin(otheta+itheta)*irad*penpos); if (oldx==-100) { oldx = x; oldy = y; startx = x; starty = y; } else if (x==startx && y==starty) { if (canQuit) break; } else canQuit = true; g.drawLine(oldx, oldy, x, y); oldx = x; oldy = y; } } public void redraw(double outside, double inside, double penpos) { this.outside = outside; this.inside = inside; this.penpos = penpos; repaint(); } } class SpiroControls extends Panel { TextField s; TextField e; TextField r; SpiroCanvas canvas; public SpiroControls(SpiroCanvas canvas) { this.canvas = canvas; add(s = new TextField("120", 5)); add(e = new TextField("40", 5)); add(r = new TextField("0.9", 5)); add(new Button("Draw")); } public boolean action(Event ev, Object arg) { if (ev.target instanceof Button) { Double d1 = new Double(s.getText().trim()); Double d2 = new Double(e.getText().trim()); Double d3 = new Double(r.getText().trim()); String label = (String)arg; canvas.redraw(d1.doubleValue(), d2.doubleValue(), d3.doubleValue()); return true; } return false; } }