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 Trirograph" or as an applet in the AppletViewer.
 */

public class Trirograph extends Applet {
	TriroControls controls;

	public void init() {
		setLayout(new BorderLayout());
		TriroCanvas c = new TriroCanvas();
		
		add("Center", c);
 		add("South", controls = new TriroControls(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("Trirograph");
		Trirograph Triro = new Trirograph();
	
		Triro.init();
		Triro.start();

		f.add("Center", Triro);
		f.resize(300, 300);
		f.show();
    }
}

class TriroCanvas extends Canvas {
	double		outside = 120;
	double		inside = 40;
	double		gear3 = 10;
	double		penpos = 0.9;
	Font		font;
    
	public void paint(Graphics g) {
		Rectangle r = bounds();
		double theta1 = 0;
		double theta2 = 0;
		double theta3 = 0;
		double ratio = (1.0*outside)/inside;
		double ratio2 = (1.0*outside)/gear3;
		double rad1 = Math.min(r.height/2.0, r.width/2.0);
		double rad2 = rad1/ratio;
		double rad3 = rad1/ratio2;
		int centerx = r.width/2;
		int centery = r.height/2;
		int oldx = -100;
		int oldy = -100;
		int startx = 0, starty = 0;
		double dx,dy;
		int x,y;
		boolean canQuit = false;

		double delta=0.05;

        g.setColor(Color.black);
        for (theta1=0.0; theta1 < 5000.0; theta1+=0.05 ) {
                theta2 = -theta1/ratio;
                theta3 = theta1/ratio2;
                dx = (Math.cos(theta2)*(rad1-rad2))
                	+(Math.cos(theta2+theta1)*(rad2-rad3))
                	+(Math.cos(theta3+theta2+theta1)*rad3*penpos);
                x = centerx+(int)(dx);
                dy = (Math.sin(theta2)*(rad1-rad2)) 
                	+ (Math.sin(theta2+theta1)*(rad2-rad3))
                	+ (Math.sin(theta3+theta2+theta1)*rad3*penpos);
                y = centery+(int)(dy);

				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 third, double penpos) {
		this.outside = outside;
		this.inside = inside;
		this.gear3 = third;
		this.penpos = penpos;
		repaint();
	}
}

class TriroControls extends Panel {
    TextField s;
    TextField e;
    TextField t;
	TextField r;
    TriroCanvas canvas;

    public TriroControls(TriroCanvas canvas) {
		this.canvas = canvas;

		add(s = new TextField("120", 5));
        add(e = new TextField("40", 5));
        add(t = new TextField("10", 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(t.getText().trim());
			Double d4 = new Double(r.getText().trim());
			String label = (String)arg;

			canvas.redraw(d1.doubleValue(), d2.doubleValue(), 
				d3.doubleValue(), d4.doubleValue());
			return true;
		}
		return false;
	}
}

	

