/* 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"); } }