/* * nm5.java - revised 28 Mar 07 - width 394, height 261 * @author jackord@kw.igs.net * pulse on n-segment string clamped at both ends for n=48, 96, 192, and 384 * time dependence from Newton's Law or FFSS and the dispersion relation * symmetry used to speed FFSS calculation */ import java.applet.Applet; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class nm5 extends Applet implements ActionListener, Runnable { int kk=0; int plt=0; int first=0; // Declarations String b1s="Pulse A"; Button b1=new Button(b1s); String b2s="Pulse B"; Button b2=new Button(b2s); String b3s="Motion"; Button b3=new Button(b3s); Choice ch=new Choice(); Checkbox ch1=new Checkbox("FFSS"); Image bim; Graphics bgr; Thread tmr; public void init() { setBackground(new Color(211, 211, 211)); ch.setBackground(getBackground()); ch.addItem("n=48"); ch.addItem("n=96"); ch.addItem("n=192"); ch.addItem("n=384"); ch1.setBackground(getBackground()); add(b1); add(b2); add(b3); add(ch); add(ch1); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); } public void start() { if (tmr==null) { tmr=new Thread(this); tmr.setPriority(Thread.MIN_PRIORITY); tmr.start(); } } public void stop() { tmr=null; plt=0; } public void run() { repaint(); } public void paint(Graphics g) { int n, no, nw, jt, del, delt, r; // Declarations n=48*(int)(Math.pow(2, ch.getSelectedIndex())); no=3*n/8; nw=n/4; int [] xx=new int[n+1]; int [] yy=new int[n+1]; double [] y=new double[n+1]; double [] v=new double[n+1]; double [] w=new double[n+1]; double [] b=new double[n+1]; double [] d=new double[n+1]; double pi=Math.PI; double z, dt; dt=n/384.; g.setColor(Color.black); g.drawRect(0, 0, 393, 260); if (first==0) { bim=createImage(392, 230); // Animation buffer bgr=bim.getGraphics(); first=1; } if (kk>0) { for (int i=0; i<=n; i=i+1) { xx[i]=4+i*384/n; } for (int i=no; i<=no+nw; i=i+1) { // Init Pulse A z=(i-no)*2*pi/nw; y[i]=40*(1-Math.cos(z)); v[i]=-40*2*pi/nw*Math.sin(z); if (kk==2) { // Init Pulse B v[i]=v[i]*Math.cos(4*z)+y[i]*4*2*pi/nw*Math.sin(4*z); y[i]=y[i]*Math.cos(4*z); } } if (ch1.getState()==false) { dt=dt/20; for (int i=no; i<=no+nw; i=i+1) { // Feynman half-step v[i]=v[i]+(y[i-1]+y[i+1]-2*y[i])*dt/2; } } else { for (int i=1; i<=n-1; i=i+1) { w[i]=2*Math.sin(pi*i/2/n); // Mode frequencies for (int j=1; j<=n-1; j=j+1) { // FFSS coefficients b[i]=b[i]+2*y[j]*Math.sin(pi*i*j/n)/n; d[i]=d[i]+2*v[j]/w[i]*Math.sin(pi*i*j/n)/n; } } } jt=0; yy[0]=115; yy[n]=yy[0]; r=3; long tt=System.currentTimeMillis(); del=24; do { // Main loop bgr.setColor(getBackground()); // Clear plot buffer bgr.fillRect(0, 0, 392, 230); bgr.setColor(Color.black); bgr.drawLine(4, 95, 4, 135); bgr.drawLine(388, 95, 388, 135); bgr.setColor(Color.blue); for (int i=1; i<=n-1; i=i+1) { // Draw blue string yy[i]=115-(int)(y[i]+.5); } bgr.drawPolyline(xx, yy, n+1); if (n==48) { for (int i=0; i<=n; i=i+1) { bgr.fillArc(xx[i]-r, yy[i]-r, 2*r+1, 2*r+1, 0, 360); } } g.drawImage(bim, 1, 29, null); // Show plot buffer jt=jt+1; // Step time if (ch1.getState()==false) { for (int j=1; j<=20; j=j+1) { for (int i=1; i<=n-1; i=i+1) { // Step y[] y[i]=y[i]+v[i]*dt; } for (int i=1; i<=n-1; i=i+1) { // Step v[] (F=ma) v[i]=v[i]+(y[i-1]+y[i+1]-2*y[i])*dt; } } } else { for (int i=1; i<=n-1; i=i+1) { y[i]=0; for (int k=1; k<=n-1; k=k+2) { y[i]=y[i]+b[k]*Math.sin(pi*i*k/n)*Math.cos(w[k]*jt*dt); } for (int k=2; k<=n-2; k=k+2) { y[i]=y[i]+d[k]*Math.sin(pi*i*k/n)*Math.sin(w[k]*jt*dt); } } } if (tt>System.currentTimeMillis()) { delt=del; } else { delt=0; } try { Thread.sleep(delt); } catch (InterruptedException e) { stop(); } tt=tt+del; if (jt==769) { kk=0; plt=0; } } while (plt==1); // Close main loop } stop(); } public void actionPerformed(ActionEvent e) { // Buttons String tst; tst=e.getActionCommand(); if (b1s.equals(tst)) { kk=1; start(); } // Pulse A if (b2s.equals(tst)) { kk=2; start(); } // Pulse B if (b3s.equals(tst)) { if (kk>0) { plt=1; } start(); } } }