/*

Newton's cradle on a ring (without gravity)

The numbers are the anticlockwise momenta of the balls.

They start out equally spaced (so that they don't overlap)

*/ import java.awt.*; import java.awt.event.*; import java.applet.*; import java.net.URL; //import java.text.NumberFormat; //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public class lppl extends Applet implements Runnable, ComponentListener { Thread thread1=null; Image image1; String message1; int size0x,size0y; int size1x,size1y,dx1,dy1,xoff,yoff; int imx,imy; int nballs; int bMarked[]; double uu[],vv[]; AudioClip acBump; Image imBall1,imBall2; int delay; //========== My own methods ========== public int sgn(int i) {return (i>0?1:0)-(i<0?1:0);} public void myInit() { } public void myPaint(Graphics realg) { realg.drawImage (image1, 0, 0, null); } public void myUpdate() { Graphics g; if (image1==null) return; g=image1.getGraphics(); g.setColor (Color.white); g.fillRect (0, 0, size1x, size1y); g.setColor (Color.black); int n,m; int X1,Y1; int XR,YR,XC,YC; double ballRad,du,dum; final double dt=0.003; ballRad=0.007; XC = size1x/2; YC = size1y/2; XR = size1x*2/5; YR = size1y*2/5; g.setColor(new Color(0xCCCCCC)); g.drawOval(XC-XR, YC-YR-1, XR+XR, YR+YR); g.setColor(Color.gray); g.drawOval(XC-XR+0, YC-YR+0, XR+XR, YR+YR); g.setColor(Color.black); g.drawOval(XC-XR+0, YC-YR+1, XR+XR, YR+YR); for (n=0; n0) bMarked[n]--; for (m=0; m0) g.drawImage(imBall2, X1-imx/2, Y1-imy/2, null); else g.drawImage(imBall1, X1-imx/2, Y1-imy/2, null); g.setColor(Color.white); g.drawString(Integer.toString(n), X1-3, Y1+3); } //NumberFormat nf = NumberFormat.getInstance(); //nf.setMaximumFractionDigits(2); int X2,idum,barThick=16,barSpace=20; for (n=0; nX2) {idum=X1;X1=X2;X2=idum;} g.setColor(Color.red); g.fillRect(X1, Y1, X2-X1, barThick); */ g.setColor(Color.black); g.drawString("p"+Integer.toString(n)+" = " + //nf.format(vv[n]*10000), Integer.toString((int)(vv[n]*100)), size1x/2-16, Y1); //g.drawString(Integer.toString(n), size1x/2-16, Y1); } } //========== Extend Applet: init(), run(), paint(), update() ========== public void init() { try { acBump = getAudioClip(getCodeBase(), "bubble1.wav"); imBall1 = getImage(getCodeBase(), "ball.blue.gif"); imBall2 = getImage(getCodeBase(), "ball.red.gif"); //imBall1 = getImage(getCodeBase(), "smiley.png"); // imBall2 = getImage(getCodeBase(), "frowney.png"); } catch (Exception e2) {} try {nballs=Integer.parseInt(getParameter("NBALLS"));} catch (Exception e) {nballs=10;} try {delay=Integer.parseInt(getParameter("DELAY"));} catch (Exception e) {delay=100;} uu = new double[nballs]; vv = new double[nballs]; bMarked = new int[nballs]; int n,m; for (n=0; nuu[n]) {ddum=uu[m];uu[m]=uu[n];uu[n]=ddum;} } } setBackground(Color.white); addComponentListener(this); componentResized(null); // Naughty hack myUpdate(); repaint(); thread1=new Thread(this); thread1.start(); } public void run() {//draw .... while (true) { myUpdate(); repaint(); try {Thread.sleep(delay);} catch (Exception e) {} } } public void paint(Graphics g) {myPaint(g);} public void update(Graphics g){myPaint(g);} //========== Implement ComponentListener ========== public void componentHidden(ComponentEvent e){} public void componentMoved(ComponentEvent e){} public void componentShown(ComponentEvent e) {} public void componentResized(ComponentEvent e) { size0x=getSize().width; size0y=getSize().height; size1x=size0x; size1y=size0y; imx=32; imy=32; image1=createImage(size1x, size1y); imBall1 = imBall1.getScaledInstance(imx, imy, Image.SCALE_SMOOTH); imBall2 = imBall2.getScaledInstance(imx, imy, Image.SCALE_SMOOTH); myUpdate(); repaint(); } }