//
/* ----------------------------------------------------------------------------------------------
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;
}
}
}
//戻る