/* * nm4.java - revised 28 Mar 07 - width 526, height 261 * @author jack@ord.ca * n-segment string clamped at both ends for n=8, 48, 96, 192, and 384 * time dependence from FFSS or directly from Newton's law * 'Pluck' and 'Pulse' initial displacements * y[n/4] plotted versus time */ import java.applet.Applet; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class nm4 extends Applet implements ActionListener, Runnable { int kk=0; int plt=0; int first=0; // Declarations String b1s="Pluck"; Button b1=new Button(b1s); String b2s="Pulse"; 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()); ch1.setBackground(getBackground()); ch.addItem("n=8"); ch.addItem("n= 48"); ch.addItem("n= 96"); ch.addItem("n=192"); ch.addItem("n=384"); 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, x1, y1, x2, y2, r, jt, del, delt; // Declarations int [] nn=new int[5]; nn[0]=8; nn[1]=48; nn[2]=96; nn[3]=192; nn[4]=384; n=nn[ch.getSelectedIndex()]; 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 [] b=new double[n+1]; double [] w=new double[n+1]; double dt, pi; g.setColor(Color.black); g.drawRect(0, 0, 525, 260); g.drawLine(395, 144, 523, 144); // y[n/4] plot axis g.setColor(Color.red); dt=n/384.; pi=Math.PI; if (first==0) { bim=createImage(393, 230); // Animation buffer bgr=bim.getGraphics(); first=1; } if (kk>0) { for (int i=0; i<=n; i=i+1) { xx[i]=4+384/n*i; } if (kk==1) { // Init pluck for (int i=0; i<=n/2; i=i+1) { y[i]=224.*i/n; y[n-i]=y[i]; } } if (kk==2) { // Init pulse for (int i=3*n/8; i<=n/2; i=i+1) { y[i]=896.*(i-3*n/8)/n; y[n-i]=y[i]; } } if (ch1.getState()==true) { for (int i=1; i<=n-1; i=i+2) { 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; } } } else { dt=dt/20; for (int i=1; i<=n-1; i=i+1) { // Feynman half-step v[i]=v[i]+(y[i-1]+y[i+1]-2*y[i])*dt/2; } } jt=0; x1=395; y1=144-(int)(y[n/4]+.5); r=3; long tt=System.currentTimeMillis(); del=12; do { // Main loop x2=395+(int)(jt*128/768); y2=144-(int)(y[n/4]+.5); g.drawLine(x1, y1, x2, y2); x1=x2; y1=y2; // Plot y[n/4] versus t bgr.setColor(getBackground()); // Clear plot buffer bgr.fillRect(0, 0, 393, 230); bgr.setColor(Color.black); bgr.drawLine(4, 95, 4, 135); bgr.drawLine(388, 95, 388, 135); bgr.setColor(Color.blue); for (int i=0; i<=n; i=i+1) { // Draw blue string yy[i]=115-(int)(y[i]+.5); } bgr.drawPolyline(xx, yy, n+1); if (n<96) { for (int i=0; i<=n; i=i+1) { if (i==n/4) { bgr.setColor(Color.red); } bgr.fillArc(xx[i]-r, yy[i]-r, 2*r+1, 2*r+1, 0, 360); if (i==n/4) { bgr.setColor(Color.blue); } } } g.drawImage(bim, 1, 29, null); // Show plot buffer jt=jt+1; // Step time if (ch1.getState()==true) { // Series for (int i=1; i<=n/2; 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); } y[n-i]=y[i]; } } else { // F = Ma 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; } } } 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; } if (b2s.equals(tst)) { kk=2; } if ((b3s.equals(tst))&&(kk>0)) { plt=1; } start(); } }