//
/* ---------------------------------------------------------------------------------------------- semi_cnd.java 半導体 ver. 1.00 (JDK 1.02) ueyama@infonet.co.jp 1999.03.02 ---------------------------------------------------------------------------------------------- */ import java.applet.Applet; import java.awt.*; import java.util.*; import java.awt.image.*; public class semi_cnd extends Applet implements Runnable { int Btn=0; // クリックされたボタンの No. int Atom[][]=new int[7][5]; // 0: Silicon 1: arsenic 2: boron int Ex[][][]=new int[7][5][4]; // 電子位置 X int Ey[][][]=new int[7][5][4]; // 電子位置 Y int Bx0=0, By0=0; // 正孔初期位置 int NorP=0; // 2: P型 1: N型 0:真性半導体 int Hx=0, Hy=0, He; // hole の位置 int Tx=999, Ty=999, Te=0; int Wait=256; int Ww=size().width, Wh=size().height; int Ax=0,Ay=0, Bx=0,By=0; boolean Sw=false; // t: ON f: OFF Button bt_n, bt_p, bt_t, bt_slow, bt_fast, bt_sw; Graphics gr; Thread th=null; Color electron =new Color(51,102,255); Color free_electron =new Color(0,51,204); Color hole =new Color(255,51,153); Color transient_hole =new Color(153,153,153); int R,G,B, Bg; int Data[]=new int[500*285]; int T; Image img; Image Gif; Random Rnd=new Random(); /* position of electrons (Hph); | | | | ---- ---- (3) ○ ---- ---- (2) | | | | (0)(1) */ // Hpx[(Te/2)?Hx%2:Hy%2][Te][0 or 1; (ramdom)] // next Hole data // position of electrons; 0 1 2 3 0 1 2 3 int Hpx[][][]={{{0,0},{0,0},{ 1,1},{ 1,1}},{{0,0},{0,0},{ 1,1},{ 1,1}}}; int Hpy[][][]={{{0,1},{0,1},{-1,0},{-1,0}},{{0,1},{0,1},{-1,0},{-1,0}}}; int Hph[][][]={{{3,3},{3,3},{ 0,0},{ 0,0}},{{2,2},{2,2},{ 1,1},{ 1,1}}}; public void start() { if(th==null) { th=new Thread(this); th.start(); } } public void init() { R=Integer.parseInt(getParameter("bg_red")); G=Integer.parseInt(getParameter("bg_green")); B=Integer.parseInt(getParameter("bg_blue")); Bg=0xff000000+R*0x10000+G*0x100+B; setBackground(new Color(R,G,B)); MediaTracker mt=new MediaTracker(this); Gif=getImage(getCodeBase(),"semi_cnd.gif"); mt.addImage(Gif, 0); try { mt.waitForID(0); } catch(InterruptedException e){}; Panel p=new Panel(); p.add(bt_n =new Button("N")); p.add(bt_p =new Button("P")); p.add(bt_t =new Button("T")); p.add(bt_slow=new Button("<<")); p.add(bt_fast=new Button(">>")); p.add(bt_sw =new Button(" ON ")); setLayout(new BorderLayout()); add("South",p); atom_init(); gr=getGraphics(); img=createImage(500,285); } // 画像の表示 m=0:原子 n=0:Silicon 1:arsenic 2:boron m=1:電極 n=0:"+" n=1:"-" public void dsp_a(int x, int y, int m, int n, Graphics g) { Graphics gx=g.create(); int l=(m==0)?23:36, o=(m==0)?17:0; gx.clipRect(x+o,y+o,l,l); gx.drawImage(Gif,x+o-(m*69+n*l),y+o,this); gx.dispose(); } public void atom_init() { int x,y; for(x=0;x<7;x++) { for(y=0;y<5;y++) { Atom[x][y]=0; Ex[x][y][0]=50+x*57+22-4; Ey[x][y][0]=(y+1)*57-4; Ex[x][y][1]=50+x*57+33-4; Ey[x][y][1]=(y+1)*57-4; Ex[x][y][2]=50+(x+1)*57-4; Ey[x][y][2]=y*57+33-4; Ex[x][y][3]=50+(x+1)*57-4; Ey[x][y][3]=y*57+22-4; } } } public boolean collision(int x, int y) { int ex, ey; ex=(x+4-50)%57; ey=(y+4)%57; if((28-ex)*(28-ex)+(28-ey)*(28-ey)<=256) return true; // 原子核との衝突 !! else return false; } public int random_position() { int rp; rp=Rnd.nextInt()&255; if(rp>170) return -1; else if(rp>85) return 1; else return 0; } public void free_electron() // 自由電子の表示 { int x,y, rx,ry; Graphics ge=gr.create(); ge.clipRect(55,6,390,276); for(x=0;x<7;x++) { for(y=0;y<5;y++) { if(Atom[x][y]==1) { if(Sw) { rx=random_position(); ry=random_position(); if(collision(Ax-(3+ry),Ay+ry)) Ay-=ry; else { Ax-=(3+ry); Ay+=ry; } if(Ax<53) { Ax=447; while(true) { Ay=Rnd.nextInt()&4095; Ay/=24; Ay+=57; if(Ay%57<16 || Ay%57>41) break; } } } ge.setColor(free_electron); ge.fillOval(Ax,Ay,9,9); } } } ge.dispose(); } public void bg_edit(int c) { int x,y,n; for(x=0;x<9;x++) { for(y=0;y<9;y++) { if((x-4)*(x-4)+(y-4)*(y-4)>16) n=Bg; else n=c; Data[(By0+y)*500+Bx0+x]=n; Data[(By0+y)*500+Bx0+x]=c; Data[(By0+y)*500+Bx0+x]=n; } } } public void hole() { int c, i,j, x,y, rx,ry, m,n, nh, tx,ty; Graphics gh=gr.create(); gh.clipRect(55,6,390,276); for(x=0;x<7;x++) { for(y=0;y<5;y++) { if(Atom[x][y]==2) { if(Math.abs(Bx-Tx)<2 && Math.abs(By-Ty)<2 && T>10) { if(Tx>60) { gh.setColor(electron); gh.fillOval(Tx,Ty,9,9); } gh.setColor(hole); gh.fillOval(Bx0,By0,9,9); bg_edit(0xff3366ff); Tx=Bx0; Ty=By0; Te=He; while(true) { n=Rnd.nextInt()&1; Hx=(Tx-50)/57; Hy=Ty/57; m=(Te/2==0)? Hx%2:Hy%2; i=Hpx[m][Te][n]; j=Hpy[m][Te][n]; nh=Hph[m][Te][n]; Hy+=j; He=nh; if(Hy>=0 && Hy<5 && Ey[Hx][Hy][He]<270) break; } Hx+=i; if(Hx==7) { Hx=0; Tx=52; } Bx=Ex[Hx][Hy][He]; By=Ey[Hx][Hy][He]; Bx0=Bx; By0=By; T=0; } if(Sw) { gh.setColor(transient_hole); gh.fillOval(Bx0,By0,9,9); bg_edit(0xff666666); rx=random_position()+((Bx-Tx>0)?-1:1); ry=random_position()+((By-Ty>0)?-1:1); if(collision(Bx+rx,By+ry)) { Bx-=rx; By-=ry; } else { Bx+=rx; By+=ry; } gh.setColor(free_electron); gh.fillOval(Bx,By,9,9); // electron } } } } gh.dispose(); } public void paint(Graphics g) { int i,j,x,y,e,n,nh,rx,ry; int qx,qy, x0,y0; rx=0; ry=0; qx=(Tx-50)/57; qy=Ty/57; g.clearRect(0,0,Ww,Wh); g.setColor(new Color(255,204,230)); // 電極の表示 g.fillRect(0,0,55,285); g.setColor(new Color(204,204,255)); g.fillRect(445,0,55,285); if(Sw) { dsp_a(10,124,1,0,gr); // 電極の表示 dsp_a(455,124,1,1,gr); } g.clipRect(55,6,390,276); for(x=0;x<7;x++) // 原子の表示 { for(y=0;y<5;y++) { x0=x%2*11+22; y0=y%2*11+22; g.setColor(new Color(0,0,0)); g.fillRect(50+x*57,y*57+x%2*11+22,57,2); g.fillRect(50+x*57+y%2*11+22,y*57,2,57); g.setColor(new Color(153,153,153)); for(i=1;i<19;i+=2) { g.fillRect(50+x*57+i*3,y*57+(x+1)%2*11+22,3,2); g.fillRect(50+x*57+(y+1)%2*11+22,y*57+i*3,2,3); } if(Atom[x][y]==1) // arsenic { g.setColor(new Color(0,0,0)); g.drawLine(50+x*57+49,y*57+6,50+x*57+29,y*57+26); g.drawLine(50+x*57+49,y*57+7,50+x*57+29,y*57+27); g.drawLine(50+x*57+50,y*57+7,50+x*57+30,y*57+27); } if(Atom[x][y]==2) // boron { g.setColor(new Color(153,153,153)); g.fillRect(50+x*57+29,y*57+x%2*11+22,28,2); g.fillRect(50+x*57+29,y*57+(x+1)%2*11+22,28,2); g.setColor(new Color(R,G,B)); for(i=10;i<19;i+=2) { g.fillRect(50+x*57+i*3,y*57+x%2*11+22,3,2); g.fillRect(50+x*57+i*3,y*57+(x+1)%2*11+22,3,2); } g.setColor(new Color(0,0,0)); } } } for(x=0;x<7;x++) // 原子核の表示 { for(y=0;y<5;y++) dsp_a(50+x*57,y*57,0,Atom[x][y],g); } g.setColor(electron); for(x=0;x<7;x++) // 電子の表示 { for(y=0;y<5;y++) { for(e=0;e<4;e++) { if(NorP==2 && x==qx && y==qy && e==Te) g.setColor(hole); g.fillOval(Ex[x][y][e],Ey[x][y][e],9,9); if(NorP==2) g.setColor(electron); } } } } public void run() { int x,y, r,g,b, ex,ey; while(th!=null) { if(NorP==1) free_electron(); if(NorP==2) hole(); try { th.sleep(Wait); } catch (InterruptedException e){} T++; if(Ax*Ay+Bx*By>0) { Graphics gx=gr.create(); gx.clipRect(55,6,390,276); ex=(NorP==1)?Ax:Bx; ey=(NorP==1)?Ay:By; for(x=0;x<9;x++) { for(y=0;y<9;y++) { r=Data[(ey+y)*500+ex+x] & 0x00ff0000; r/=0x10000; g=Data[(ey+y)*500+ex+x] & 0x0000ff00; g/=0x100; b=Data[(ey+y)*500+ex+x] & 0x000000ff; gx.setColor(new Color(r,g,b)); gx.drawRect(ex+x,ey+y,1,1); } } gx.dispose(); } // gr.fillOval(Ax,Ay,9,9); // gr.fillOval(Bx,By,9,9); } } public boolean get_pixeldata() { update(img.getGraphics()); PixelGrabber pg=new PixelGrabber(img,0,0,500,285,Data,0,500); try { pg.grabPixels(); // 画像データの取得 } catch (InterruptedException ie) {return false;} if((pg.status() & ImageObserver.ABORT) !=0) {return false;} return true; } public boolean action(Event e, Object o) { Btn=0; if(e.target==bt_n) Btn=1; else if(e.target==bt_p) Btn=2; else if(e.target==bt_t) { atom_init(); NorP=0; Ax=0; Ay=0; Bx=0; By=0; Tx=999; Ty=999; repaint(); get_pixeldata(); } else if(e.target==bt_slow) { Wait*=2; bt_fast.enable(); } else if(e.target==bt_fast) { if(Wait>64) Wait/=2; else bt_fast.disable(); } else if(e.target==bt_sw) { Sw=!Sw; bt_sw.setLabel((Sw)?"OFF":" ON "); if(Sw) { dsp_a(10,124,1,0,gr); // 電極の表示 dsp_a(455,124,1,1,gr); bt_n.disable(); bt_p.disable(); bt_t.disable(); } else { gr.setColor(new Color(255,204,230)); gr.fillRect(0,124,55,55); gr.setColor(new Color(204,204,255)); gr.fillRect(445,124,55,55); bt_n.enable(); bt_p.enable(); bt_t.enable(); } } if(Btn>0) { bt_n.disable(); bt_p.disable(); bt_t.disable(); bt_sw.disable(); } return true; } public boolean mouseDown(Event e, int x, int y) { int i,j,k; if(x>55 && x<445 && y<278) { i=(x-50)/57; j=y/57; k=(i%2==0)?3:2; if(Btn==1 || Btn==2) { atom_init(); Atom[i][j]=Btn; NorP=Btn; T=0; } if(Btn==1) // arsenic doped { Ax=50+i*57+50-4; Ay=j*57+7-4; Bx=0; By=0; Tx=999; Ty=999; } if(Btn==2) // boron doped { Tx=Ex[i][j][k]; Ty=Ey[i][j][k]; Te=k; Bx=Tx; By=Ty; Bx0=Bx; By0=By; He=k; } if(Btn>0) { repaint(); get_pixeldata(); } bt_n.enable(); bt_p.enable(); bt_t.enable(); bt_sw.enable(); Btn=0; } return true; } public void stop() { if(th!=null) { th.stop(); th=null; } } } //戻る