/** applet No. 1123 * * snow reflection - photon transfer Monte-Carlo simulation 2D * - multi thread MCS2D :: display - asynchronous * * Created by Ikeuchi Mitsuru on February 17 2007. * Copyright (c) 2007 Ikeuchi Mitsuru. All rights reserved. * * ver 0.0.1 2007.02.17 created * ver 0.0.2 2007.06.16 improved code * */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class snowWhitePTMCS2D extends Applet implements MouseListener, MouseMotionListener, ItemListener, ActionListener, AdjustmentListener, Runnable { // ------------------------------------ preset field ----------- Thread th = null; // for run()-paint() thread PhotonTransferMCS2D mcs = null; DrawGraph2D dg2d = new DrawGraph2D(); // for event Choice ch_view; Button bt_reset, bt_startStop, bt_beamSW; Scrollbar sc_intensity, sc_scatter, sc_absorb, sc_scale; // for off-paint buffer private Dimension dim; private Image imgOff; private Graphics gOff; private int dgX, dgY, dgXb, dgYb; // mouse private int sleepTime = 50; private int dispMode = 1; private int thCount = 0; // ------------------------------ applet main thread ----------- public void init() { resize(630,420); setBackground(Color.white); dim = getSize(); imgOff = createImage(dim.width,dim.height); gOff = imgOff.getGraphics(); ch_view = new Choice(); ch_view.add("ball"); ch_view.add("line"); ch_view.addItemListener(this); ch_view.select("line"); bt_reset = new Button("reset"); bt_reset.addActionListener(this); bt_startStop = new Button("start/stop"); bt_startStop.addActionListener(this); bt_beamSW = new Button("beam ON/OFF"); bt_beamSW.addActionListener(this); sc_intensity = new Scrollbar(Scrollbar.HORIZONTAL,100,10,0,110); sc_intensity.addAdjustmentListener(this); sc_scatter = new Scrollbar(Scrollbar.HORIZONTAL,20,10,0,110); sc_scatter.addAdjustmentListener(this); sc_absorb = new Scrollbar(Scrollbar.HORIZONTAL,10,10,0,110); sc_absorb.addAdjustmentListener(this); sc_scale = new Scrollbar(Scrollbar.HORIZONTAL,100,10,50,310); sc_scale.addAdjustmentListener(this); addMouseListener(this); addMouseMotionListener(this); setLayout(new BorderLayout()); Panel pnl = new Panel(); pnl.setLayout(new GridLayout(2,6,5,0)); //pnl.add(new Label(" ")); pnl.add(bt_reset); pnl.add(bt_startStop); pnl.add(new Label(" ")); pnl.add(bt_beamSW); pnl.add(new Label(" ")); pnl.add(new Label(" ")); pnl.add(sc_intensity); pnl.add(sc_scatter); pnl.add(sc_absorb); pnl.add(new Label(" ")); pnl.add(sc_scale); pnl.add(ch_view); add(pnl,"North"); } public void start() { if (mcs == null) { mcs = new PhotonTransferMCS2D(); mcs.start(); } if (th == null) { th = new Thread(this); th.start(); } } public void stop() { if (th != null) th = null; if (mcs != null) mcs = null; } // ---------------------------------- event listener ----------- public void itemStateChanged(ItemEvent ev){ if (ev.getSource() == ch_view) { dispMode = ch_view.getSelectedIndex(); } } public void actionPerformed(ActionEvent ev){ if(ev.getSource() == bt_reset){ mcs.reset(); thCount = 0; } else if (ev.getSource() == bt_startStop){ if (mcs.getStartSW()==0) { mcs.setStartSW(1); } else { mcs.setStartSW(0); } } else if (ev.getSource() == bt_beamSW){ if (mcs.getBeamSW()==0) { mcs.setBeamSW(1); } else { mcs.setBeamSW(0); } } } public void adjustmentValueChanged(AdjustmentEvent ev){ if (ev.getSource() == sc_intensity) { mcs.setBeamIntensity( 0.01*(double)(sc_intensity.getValue()) ); } else if (ev.getSource() == sc_scatter) { mcs.setMediaScatter( 1.0e-4*(double)(sc_scatter.getValue()) ); } else if (ev.getSource() == sc_absorb) { mcs.setMediaAbsorb( 1.0e-5*(double)(sc_absorb.getValue()) ); } else if (ev.getSource() == sc_scale) { dg2d.setScale( 0.01*(double)(sc_scale.getValue()) ); } } public void mousePressed(MouseEvent ev){ } public void mouseReleased(MouseEvent ev){ dgXb = 0; dgYb = 0; dgX = 0; dgY = 0; } public void mouseClicked(MouseEvent ev){ } public void mouseEntered(MouseEvent ev){ } public void mouseExited (MouseEvent ev){ } public void mouseMoved (MouseEvent ev){ } public void mouseDragged(MouseEvent ev){ dgXb = dgX; dgYb = dgY; dgX=ev.getX(); dgY=ev.getY(); if (dgXb==0 && dgYb==0) { dgXb = dgX; dgYb = dgY; } dg2d.setViewDelta( (dgX-dgXb), (dgY-dgYb) ); } // ========================= run() - paint() loop ============== public void run() { while (th != null) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } thCount += 1; offPaint(); repaint(); } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.drawImage(imgOff,0,0,this); } private void offPaint() { if (mcs != null) { dg2d.plotGraph2D(gOff, mcs, dispMode, thCount); } } } // =============================== draw graph 2D class =========== class DrawGraph2D { private Graphics gOff; private PhotonTransferMCS2D mcs; private double dt = mcs.dt; private double dx = mcs.dx; private double dy = mcs.dy; private int Nsx = mcs.Nsx; private int Nsy = mcs.Nsy; private double xMax = Nsx*dx; private double yMax = Nsy*dy; private int Nmt = mcs.Nmt; private double dispScale = 400.0/xMax; private double viewScale = 1.0; private int gx0 = 30; private int gy0 = 110; private int xImageLoc = gx0; private int yImageLoc = gy0; private double xShift = 0.0; private double yShift = 0.0; private int rdf[] = new int[120]; private int drawnCount = 0; // ------------------------------- class constructor ----------- DrawGraph2D() { } // ----------------------------------- class methods ----------- public void plotGraph2D(Graphics gg, PhotonTransferMCS2D mcs2d, int dispMode, int thCount) { int gbh,mcsCount; double invmfp; gOff = gg; mcs = mcs2d; if (mcs==null) return; mcsCount = mcs.getCount(); //if (mcsCount==drawnCount) return; drawnCount = mcsCount; gOff.setColor(Color.white); gOff.fillRect(0,0,630,420); if (dispMode==0) { // ball mediaPlot(); ballPlot(); } else if (dispMode==1) { // line mediaPlot(); linePlot(); } else if (dispMode==2) { ; } gbh = 630/6; gOff.setColor(Color.black); gOff.drawString("I="+(float)(mcs.getBeamIntensity())+"",gbh*0+20,70); gOff.drawString("Ssc="+(float)(mcs.getMediaScatter())+"",gbh*1+20,70); gOff.drawString("Sab="+(float)(mcs.getMediaAbsorb())+"",gbh*2+20,70); gOff.drawString("scale="+(int)(viewScale*100.0+0.499)+"%",gbh*4+10,70); gOff.drawString("view",gbh*5+10,70); gOff.setColor(Color.blue); gOff.drawString("t="+(int)(mcs.getTime()*1.0e14+0.5)/100.0+" ps",gbh*0+10,90); invmfp = mcs.getInvMeanFreePath(1); if (invmfp<1.0e-8) { gOff.drawString("scatter mean free path = infinity",120,90); } else { gOff.drawString("scatter mean free path = "+(int)(100000.0/invmfp)/100.0+" mm",120,90); } invmfp = mcs.getInvMeanFreePath(2); if (invmfp<1.0e-8) { gOff.drawString("absorb mean free path = infinity",400,90); } else { gOff.drawString("absorb mean free path = "+(int)(100000.0/invmfp)/100.0+" mm",400,90); } gOff.setColor(Color.black); gOff.drawString("density = 1.0E6",480,110); gOff.drawString("thickness = 10.0 mm",480,130); gOff.setColor(Color.black); gOff.drawString("photon count",480,200); gOff.drawString("generated = "+mcs.getPhotnCount(0)+" ",480,220); gOff.drawString("forward = "+mcs.getPhotnCount(1)+" ",480,240); gOff.drawString("backward = "+mcs.getPhotnCount(2)+" ",480,260); gOff.drawString("absorbed = "+mcs.getPhotnCount(3)+" ",480,280); gOff.setColor(Color.black); gOff.drawString("thread count",480,340); gOff.drawString("MCS = "+mcs.getCount()+" ",480,360); gOff.drawString("disp = "+thCount+" ",480,380); } // ------------------------------------ plot methods ----------- private void ballPlot() { int i,ix,iy,ir; double sc,tm; sc = viewScale*dispScale; for (i=0; i0) { gOff.setColor(Color.getHSBColor(0.6f,0.95f,0.9f)); } else { gOff.setColor(Color.getHSBColor(0.05f,0.95f,0.9f)); } gOff.drawOval(ix-ir/2,iy-ir/2, ir, ir); } } } private void linePlot() { int i,ix,iy,ix2,iy2; double sc,scc; sc = viewScale*dispScale; scc = viewScale*3.0e8*0.01; for (i=0; i0) { gOff.setColor(Color.getHSBColor(0.6f,0.95f,0.9f)); } else { gOff.setColor(Color.getHSBColor(0.05f,0.95f,0.9f)); } gOff.drawLine(ix,iy, ix2, iy2); } } } private void mediaPlot() { int i,j,ix,iy,ir; double sc,tm; sc = viewScale*dispScale; ir = (int)(dx*sc+0.99); for (i=0; i0) { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } } } // --------------------------- set initial condition ----------- private void setInitialCondition() { int i,j,ithick; count = 0; t = 0.0; ithick = 100; for (i=0; i=Nsx/4 && iMath.random()) { generatePhoton(1); } } private void generatePhoton(int knd) { int ip; ip = seekPhotonID(); if (ip<0) return; kind[ip] = knd; xx[ip] = 0.0; yy[ip] = dy*(Nsy/2+Nsy/4*(Math.random()-0.5)); vx[ip] = lightSpeed; vy[ip] = 0.0; photonCount[0] += 1; } private int seekPhotonID() { int i,ir,ip; ir = (int)(0.99999*(Nmt-1)*Math.random()); for (i=0; i0) { xx[i] += vx[i]*dt; yy[i] += vy[i]*dt; if (xx[i]<0.0) { photonCount[2] +=1; kind[i] = 0; } if (xx[i]>=xMax) { photonCount[1] +=1; kind[i] = 0; } if (yy[i]<0.0) { yy[i] = yy[i] + yMax; } if (yy[i]>=yMax) { yy[i] = yy[i] - yMax; } } } } private void photonScatter() { int i,ix,iy,k; double ncdt,ss,sa; for (i=0; i0) { ix = (int)(xx[i]/dx); if (ix>=Nsx) ix = Nsx-1; if (ix<0) ix = 0; iy = (int)(yy[i]/dy); if (iy>=Nsy) iy = Nsy-1; if (iy<0) iy = 0; k = mediaKind[ix][iy]; ncdt = media[k][0]*lightSpeed*dt; ss = media[k][1]; sa = media[k][2]; if (ncdt*ss>Math.random()) { scatter(i); } else if (ncdt*sa>Math.random()) { photonCount[3] +=1; kind[i] = 0; } } } } private void scatter(int i) { double theta,s,c,vvx,vvy; theta = Math.PI*(2.0*Math.random()-1.0); s = Math.sin(theta); c = Math.cos(theta); vvx = c*vx[i] - s*vy[i]; vvy = s*vx[i] + c*vy[i]; vx[i] = vvx; vy[i] = vvy; } // ------------------------------------- I/O methods ----------- // control public void reset() { resetSW = 1; } public void setStartSW(int sw) { startSW = sw; } public int getStartSW() { return startSW; } public void setStepSW() { stepSW = 1; } public int getCount() { return count; } public void setMediaScatter(double ss) { media[1][1] = ss; } public double getMediaScatter() { return media[1][1]; } public void setMediaAbsorb(double ss) { media[1][2] = ss; } public double getMediaAbsorb() { return media[1][2]; } public void setBeamSW(int sw) { beamSW = sw; } public int getBeamSW() { return beamSW; } public void setBeamIntensity(double b) { beamIntensity = b; } public double getBeamIntensity() { return beamIntensity; } // get data public double getTime() { return t; } public double getMediaKind(int i,int j) { return mediaKind[i][j]; } public int getKind(int i) { return kind[i]; } public double getxx(int i) { return xx[i]; } public double getyy(int i) { return yy[i]; } public double getvx(int i) { return vx[i]; } public double getvy(int i) { return vy[i]; } public int getPhotnCount(int i) { return photonCount[i]; } public double getInvMeanFreePath(int j) { return media[1][0]*media[1][j]; } }