import java.awt.*; import java.lang.Math; import java.applet.Applet; import java.util.Vector; public class Caustic extends Applet { int w, h; public void init() { w = size().width; h = size().height; if(h > (3*w)/5) h = (3*w)/5; resize(w, h); setLayout(new BorderLayout()); DrawPanel dp = new DrawPanel(w, h); add("Center", dp); } public boolean handleEvent(Event e) { switch (e.id) { case Event.WINDOW_DESTROY: System.exit(0); return true; default: return false; } } } class DrawPanel extends Panel { Vector lines = new Vector(); double h2, radius; int hh, w1, w2, w3, w4; public DrawPanel(int w, int h) { setBackground(Color.black); radius = 0.4*h; h2 = 0.5*h; w1 = w - (4*h)/10; w2 = w - (2*h)/10; w3 = w - h/10; w4 = w; hh = h; } public boolean handleEvent(Event e) { double y; switch (e.id) { case Event.MOUSE_DOWN: if(e.x >= w1 && e.x <= w2){ y = (h2 - e.y)/radius; if(y < 1.0 && y > -1.0) lines.addElement(new Double(y)); } if(e.x > w3){ lines.removeAllElements(); } repaint(); return true; case Event.WINDOW_DESTROY: System.exit(0); return true; default: return false; } } public void paint(Graphics g) { int np = lines.size(); double x, y, a, b, p, q; /* draw the current lines */ g.setPaintMode(); g.setColor(Color.white); g.drawOval( xscale(-1.0), yscale(1.0), (int)(2.0*radius), (int)(2.0*radius)); g.setColor(Color.yellow); g.fillRect( w1, yscale(1.0), w2-w1, (int)(2.0*radius)); g.setColor(Color.red); g.fillRect( w3, 0, w4-w3, hh); g.setColor(Color.gray); for (int i=0; i < np; i++) { y = ((Double)lines.elementAt(i)).doubleValue(); x = -Math.sqrt(1.0 - y*y); g.drawLine( xscale(x), yscale(y), w1, yscale(y)); } g.setColor(Color.yellow); for (int i=0; i < np; i++) { y = ((Double)lines.elementAt(i)).doubleValue(); x = -Math.sqrt(1.0 - y*y); a = x*x - y*y; b = 2.0*x*y; p = -a*x + b*y; q = -b*x - a*y; g.drawLine( xscale(x), yscale(y), xscale(p), yscale(q)); } } public int xscale(double x) { return (int)(x*radius + h2); } public int yscale(double y) { return (int)(-y*radius + h2); } }