/* * fsct.java - revised 17 Apr 05 - width 401, height 301 * Rutherford scattering from a fixed force center for impact parameters * less than five times distance of closest approach at head-on impact * SEQ - 26 particles at regular impact parameter increments * RND - 26 particles randomly distributed across the area of the beam * CNT - angular distribution for 500 randomly distributed particles * @author jackord@kw.igs.net */ import java.applet.Applet; import java.awt.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class fsct extends Applet implements ActionListener, Runnable { int kk=0; int first=0; double pi=Math.PI; // Declarations String b1s="SEQ"; Button b1=new Button(b1s); String b2s="RND"; Button b2=new Button(b2s); String b3s="CNT"; Button b3=new Button(b3s); Thread tmr; int [] xx=new int[81]; int [] yy=new int[81]; public void init() { setBackground(new Color(211, 211, 211)); add(b1); add(b2); add(b3); b1.addActionListener(this); b2.addActionListener(this); b3.addActionListener(this); } double hit(double y, Graphics g) { // Feynman Algorithm int phase, x1, y1, x2, y2; // with trajectory double x, vx, vy, dt, r3; x=-200; dt=1; vx=.4416; vy=0; x1=0; y1=0; r3=Math.pow((x-200)*(x-200)+(y-150)*(y-150), 1.5); vx=vx+(x-200)/r3*dt/2; vy=vy+(y-150)/r3*dt/2; phase=1; do { x=x+vx*dt; y=y+vy*dt; r3=Math.pow((x-200)*(x-200)+(y-150)*(y-150), 1.5); vx=vx+(x-200)/r3*dt; vy=vy+(y-150)/r3*dt; if (phase==2) { x2=(int)(x+.5); y2=(int)(y+.5); g.drawLine(x1, y1, x2, y2); x1=x2; y1=y2; if ((x2>400)||(y2>300)) { phase=3; } } if ((phase==1)&&(x>=0)) { x1=(int)(x+.5); y1=(int)(y+.5); phase=2; } } while ((phase<3)&&(r3<66000000)); return Math.atan2(vy, vx)/pi*180; } double ctr(double y) { // Feynman Algorithm double x, vx, vy, dt, r3; // no trajectory x=-200; dt=1; vx=.4416; vy=0; r3=Math.pow((x-200)*(x-200)+(y-150)*(y-150), 1.5); vx=vx+(x-200)/r3*dt/2; vy=vy+(y-150)/r3*dt/2; do { x=x+vx*dt; y=y+vy*dt; r3=Math.pow((x-200)*(x-200)+(y-150)*(y-150), 1.5); vx=vx+(x-200)/r3*dt; vy=vy+(y-150)/r3*dt; } while (r3<66000000); return Math.abs(Math.atan2(vy, vx)/pi*180); } double rnd() { // Random impact double x, y, r; // parameter int test=0; do { x=Math.random(); y=Math.random(); r=Math.pow((x-.5)*(x-.5)+(y-.5)*(y-.5), .5); if (r<=.5) { test=1; } } while (test==0); r=50*r; if (y<.5) { r=-r; } return 150+r; } public void start() { if (tmr==null) { tmr=new Thread(this); tmr.setPriority(Thread.MIN_PRIORITY); tmr.start(); } } public void stop() { tmr=null; } public void run() { repaint(); } public void paint(Graphics g) { // Paint double t, u; double z=125; int x1, y1, x2, y2, xorg, yorg; int [] cc=new int[20]; xorg=30; yorg=280; if (first==0) { t=2*Math.atan(.2)/pi*180; xx[0]=xorg+(int)(2*t+.5); xx[1]=xx[0]; yy[0]=yorg; yy[1]=20; for (int i=2; i<=80; i=i+1) { xx[i]=xorg+40+4*i; u=Math.tan(pi/180*(10+i)); yy[i]=yorg-(int)(10*pi/9*(1+u*u)/u/u/u+.5); if (yy[i]<20) { yy[i]=20; } } } if (kk<3) { // Scattering center g.setColor(Color.black); g.drawRect(0, 0, 400, 300); g.setColor(Color.green); g.fillArc(190, 140, 21, 21, 0, 360); g.drawArc(190, 140, 20, 20, 0, 360); g.setColor(Color.blue); if (kk==1) { // Stepped impact while (z<176) { // parameter hit(z, g); z=z+2; } } if (kk==2) { // Random distribution for (int i=0; i<=25; i=i+1) { hit(rnd(), g); } } } if (kk==3) { // 500 particle counter g.setColor(Color.blue); g.fillPolygon(xx, yy, 81); g.setFont(new Font("TimesRoman", Font.PLAIN, 14)); g.drawString("N(<60) = 440", xorg+20, yorg+17); // N with theta<60 deg g.drawString("N(>60) = 60", xorg+265, yorg+17); // N with theta>60 deg g.setColor(Color.black); for (int i=30; i<=390; i=i+20) { g.drawLine(i, 20, i, yorg); } for (int i=20; i<=280; i=i+20) { g.drawLine(xorg, i, 390, i); } g.drawString("0", xorg-3, yorg+17); g.drawString("60", 150-6, yorg+17); g.drawString("120", 270-9, yorg+17); g.drawString("180", 390-9, yorg+17); g.drawString("Theta deg", 180, yorg+17); g.drawString("Cnt", 0, 136); g.drawString("0", xorg-12, yorg+6); g.drawString("100", xorg-24, yorg+6-100); g.drawString("200", xorg-24, yorg+6-200); try { // Freeze display 2 sec Thread.sleep(2000); } catch (InterruptedException e) { stop(); } g.setColor(Color.red); for (int i=1; i<=500; i=i+1) { x1=(int)(ctr(rnd())/10); cc[x1]=cc[x1]+1; x2=xorg+20*x1; y2=yorg-cc[x1]; g.drawLine(x2, y2, x2+20, y2); } x1=0; x2=0; for (int i=2; i<=5; i=i+1) { x1=x1+cc[i]; } for (int i=6; i<=17; i=i+1) { x2=x2+cc[i]; } g.clearRect(50, 281, 80, 18); g.clearRect(290, 281, 80, 18); g.drawString("N(<60) = "+x1, xorg+20, yorg+17); // N with theta<60 deg g.drawString("N(>60) = "+x2, xorg+265, yorg+17); // N with theta>60 deg } kk=0; stop(); } public void actionPerformed(ActionEvent e) { // Action Buttons String tst; tst=e.getActionCommand(); if (b1s.equals(tst)) { kk=1; } if (b2s.equals(tst)) { kk=2; } if (b3s.equals(tst)) { kk=3; } start(); } }