/*  Simple applet to draw Limacon figures.*   @author: Wm Leler*   wm@leler.com*   http://leler.com*   copyright (c) 1996 Wm Leler*/import java.awt.*;import java.applet.*;import java.util.Random;/** A single Limacon object */class Limacon {	public int samples;		// number of samples per loop	public double frequency;	// sine wave frequency	public int loops;		// number of loops around circle	public double offset;		// r offset from zero	public Limacon() {		samples = 106;		frequency = 52.0;		loops = 1;		offset = 0.0;	}	public Limacon(int s, double f, int l, double o) {		samples = s;		frequency = f;		loops = l;		offset = o;	}	public void setFrom(Limacon lc) {		samples = lc.samples;		frequency = lc.frequency;		loops = lc.loops;		offset = lc.offset;	}	public void paint(Graphics g, int width, int height) {		if (samples <= 0) { return; }		double step = 2.0d * Math.PI / (double) samples;		int limit = samples * loops + 1;		double theta = 0.0;		int addx = width / 2;		int addy = height / 2;		double scale = ((width < height) ? addx : addy) /				(1.0 + Math.abs(offset));		double r = scale * offset;		int oldx = addx + (int) r;		int oldy = addy;		// g.setColor(Color.lightGray);		g.clearRect(0, 0, width, height);		// g.setColor(Color.black);		for (int i = 0; i < limit; i++) {			r = scale * (offset + Math.sin(theta * frequency));			int x = addx + (int) (r * Math.cos(theta));			int y = addy + (int) (r * Math.sin(theta));			g.drawLine(oldx, oldy, x, y);			oldx = x;			oldy = y;			theta += step;		}				}}/** Limacon applet */public class LimeApp extends Applet {	Limacon curlime;	TextField samples;	// text version of int	TextField frequency;	// text version of double	TextField loops;	// text version of int	TextField offset;	// text version of double	Button button;		// press for random limacon	int limenum = -1;	// current Limacon in list	static Limacon limes[];	// list of interesting Limacons	Random rand;		// random number generator	static {		limes = new Limacon[58];		limes[0]  = new Limacon(106,  52.0,       1,  0.0);		limes[1]  = new Limacon(360,  12.0,       1,  0.0);		limes[2]  = new Limacon( 12,   6.125,     8,  0.0);		limes[3]  = new Limacon( 67,  53.0,       1,  0.0);		limes[4]  = new Limacon(  4,   0.984375, 64,  0.0);		limes[5]  = new Limacon(  4,   0.0,       1,  3.0);		limes[6]  = new Limacon( 15,  51.5,       2,  0.0);		limes[7]  = new Limacon(130,  52.0,       1,  0.0);		limes[8]  = new Limacon(139,  45.0,       1,  0.0);		limes[9]  = new Limacon(200,   4.0,       1,  0.0);		limes[10] = new Limacon( 78,  52.5,       1,  0.0);		limes[11] = new Limacon( 39,  52.0,       1,  0.0);		limes[12] = new Limacon(  9,  53.4375,   16,  0.0);		limes[13] = new Limacon(  9,  53.4375,   16,  0.2);		limes[14] = new Limacon( 50,   0.03125,   8,  0.0);		limes[15] = new Limacon(  7,  48.125,     8,  1.0);		limes[16] = new Limacon( 50,  -0.05,      4,  0.0);		limes[17] = new Limacon( 50,   1.0,       1,  0.0);		limes[18] = new Limacon( 50,   1.0,       1,  1.0);		limes[19] = new Limacon( 50,   0.375,     8,  0.0);		limes[20] = new Limacon( 23,   1.375,     8,  0.0);		limes[21] = new Limacon( 50,   1.375,     8,  0.0);		limes[22] = new Limacon( 15,   2.375,     8,  0.0);		limes[23] = new Limacon( 16,   2.375,     8,  0.0);		limes[24] = new Limacon( 17,   2.375,     8,  0.0);		limes[25] = new Limacon( 18,   2.375,     8,  0.0);		limes[26] = new Limacon( 19,   2.375,     8,  0.0);		limes[27] = new Limacon( 20,   2.375,     8,  0.0);		limes[28] = new Limacon( 21,   2.375,     8,  0.0);		limes[29] = new Limacon( 22,   2.375,     8,  0.0);		limes[30] = new Limacon( 23,   2.375,     8,  0.0);		limes[31] = new Limacon( 24,   2.375,     8,  0.0);		limes[32] = new Limacon( 25,   2.375,     8,  0.0);		limes[33] = new Limacon( 26,   2.375,     8,  0.0);		limes[34] = new Limacon( 27,   2.375,     8,  0.0);		limes[35] = new Limacon( 64,  32.25,      1,  0.0);		limes[36] = new Limacon( 43,  32.25,      1,  0.0);		limes[37] = new Limacon(130,  45.0,       1,  0.0);		limes[38] = new Limacon(130,  43.0,       1,  0.0);		limes[39] = new Limacon(130,  34.0,       1,  0.0);		limes[40] = new Limacon(130,  32.0,       1,  0.0);		limes[41] = new Limacon(150,   4.125,     8,  0.0);		limes[42] = new Limacon( 74,   1.25,      4,  0.0);		limes[43] = new Limacon( 50,   0.25,      4,  0.0);		limes[44] = new Limacon( 24,  11.875,     8,  0.0);		limes[45] = new Limacon( 12,   0.09375,  32,  0.0);		limes[46] = new Limacon( 12,   0.28125,  32,  0.0);		limes[47] = new Limacon( 12,   0.65625,  32,  0.0);		limes[48] = new Limacon(153,  52.0,       1,  1.0);		limes[49] = new Limacon( 25,  14.5,       2,  1.0);		limes[50] = new Limacon( 43,  32.2,       5,  0.0);		limes[51] = new Limacon( 46,  32.2,       3,  0.0);		limes[52] = new Limacon( 46,  32.2,       5,  7.0);		limes[53] = new Limacon( 46,  32.1,      10,  4.0);		limes[54] = new Limacon(  8,   0.98,     50,  0.0);		limes[55] = new Limacon(  8,   0.98,     50,  2.0);		limes[56] = new Limacon(  4,   0.9921875,128, 0.0);		limes[57] = new Limacon( 15,   0.96875,   32, 0.0);	}	public void init()	{		rand = new Random();		curlime = new Limacon();		resize(500, 520);		setLayout(new BorderLayout());		Panel bar = new Panel();		button = new Button("Random");		bar.add(button);		bar.add(new Label("Samples"));		samples = new TextField(Integer.toString(curlime.samples), 3);		bar.add(samples);		bar.add(new Label("Freq"));		frequency = new TextField(Double.toString(curlime.frequency), 7);		bar.add(frequency);		bar.add(new Label("Loops"));		loops = new TextField(Integer.toString(curlime.loops), 2);		bar.add(loops);		bar.add(new Label("Offset"));		offset = new TextField(Double.toString(curlime.offset), 3);		bar.add(offset);		add("South", bar);		show();		System.out.println(bar.size().height);	}	public boolean action(Event evt, Object obj) {		if (evt.target == samples) {			try {				curlime.samples = Integer.parseInt(samples.getText());			} catch (NumberFormatException e) { 				showStatus("Error: samples must be an integer number");				return true;			}		}		else if (evt.target == frequency) {				try {				curlime.frequency = Double.valueOf(frequency.getText()).doubleValue();			} catch (NumberFormatException e) { 				showStatus("Error: frequency must be a floating-point number");				return true;			}		}		else if (evt.target == loops) {			try {				curlime.loops = Integer.parseInt(loops.getText());			} catch (NumberFormatException e) { 				showStatus("Error: loops must be an integer number");				return true;			}		}		else if (evt.target == offset) {			try {				curlime.offset = Double.valueOf(offset.getText()).doubleValue();			} catch (NumberFormatException e) { 				showStatus("Error: offset must be a floating-point number");				return true;			}		}		else if (evt.target == button) {	// pick random limacon			limenum = (int) (58.0 * rand.nextDouble());			if (limenum >= limes.length) limenum = 0;			curlime.setFrom(limes[limenum]);			samples.setText(Integer.toString(curlime.samples));			frequency.setText(Double.toString(curlime.frequency));			loops.setText(Integer.toString(curlime.loops));			offset.setText(Double.toString(curlime.offset));		}		else { return true; }		showStatus("");		repaint();		return true;	}	public void paint(Graphics g) {		curlime.paint(g, 500, 485);		paintComponents(g);	}	public void stop() {		play(getCodeBase(), "goodbye.au");	}	public String getAppletInfo() {		return new String("Limacon, copyright (c) 1996 Wm Leler");	}}