Fu-Kwun Hwang
|
 |
«
Embed this message
Reply #4 on: May 15, 2013, 10:32:28 am » posted from:,,Satellite Provider |
|
 The source code is available as attached file. It is also listed as following import java.awt.*; public class traffic extends java.applet.Applet implements Runnable{ int yOffset=40; TextField iField; //record time elapse double time=0.0,ts=0.; Dimension area; int N=3; //Rectangle R[]=new Rectangle[N],L[]=new Rectangle[N]; //Rectangle R2[]=new Rectangle[N],L2[]=new Rectangle[N]; //boolean Rs[]=new boolean[N],Ls[]=new boolean[N]; Image bgImage,fgImage; Graphics gb,g;//background drawing Color bgColor=Color.lightGray; car c[]=new car[N]; Label XY; String rts,STR[]={"Reset","Time"}; public void init() { setBackground(bgColor); for(int i=0;i if((rts=getParameter(STR ))!=null) STR=new String(rts); } Panel p=new Panel(); // p.add(new Label(STR[1])); // p.add(timeField=new TextField("0.0",3)); // timeField.setEditable(false); p.add(new Button(STR[0])); p.add(iField=new TextField("",3)); iField.setEditable(false); p.add(XY=new Label("( X , Y )")); //p.add(new Button("Start")); add("North",p); area=size(); area.height-=yOffset; reset(true);// false for auto start }
public boolean action(Event ev, Object arg) { if (ev.target instanceof Button) { String label = (String)arg; if(label.equals("Reset")){ reset(true); }/*else if(label.equals("Start")){ running=true; start(); }*/ }else if(ev.target==iField&&changed!=null){ double val=Double.valueOf(iField.getText()).doubleValue(); if(mode int dval=5; if(val>dval)dval=(int)val; if(clickCount==2){ for(int i=0;i car.maxCount=dval; } }else car.maxCount[mode]=dval; }else{//Vmax val=Math.abs(val); if(clickCount==2){ for(int i=0;i car.vmax=val; } }else car.vmax[mode%N]=val; } changed=null; } return true; } int xx,yy; public void reset(boolean status){ time=0.; clear(status); } String d2String(double value){ float f=(float)((int)(value*100.)/100.); String str=String.valueOf(f); if(str.indexOf(".")==-1)str+=".0"; return str; } // animation code boolean running=true; Thread animThread; long startTime=0,lastTime; long delay=50,delta; // This starts the threads. public void start(){ //Start animating! if (animThread == null) { animThread = new Thread(this); animThread.start(); } //Remember the starting time. of thread lastTime=startTime = System.currentTimeMillis(); } public void stop() { //Stop the animating thread. animThread = null; running=false; }
public void run() { //Just to be nice, lower this thread's priority Thread.currentThread().setPriority(Thread.MIN_PRIORITY); //This is the animation loop. while (Thread.currentThread() == animThread) { //Advance the animation frame. with delta time delta=System.currentTimeMillis()-lastTime; lastTime+=delta; if(running)advanced(delta/1000.); startTime+=delay; try { animThread.sleep(Math.max(0,startTime-System.currentTimeMillis())); } catch (InterruptedException e) { break; } } } void advanced(double dt){ for(int i=0;i c.advanced(dt); time+=dt; ts+=dt; if(ts>1.){ ts-=1.; //timeField.setText(String.valueOf(time)); } repaint(); } boolean rightClick=false; Color cpass=Color.green,cstop=Color.red; int mode;// 0-2:Nmax,3-5:Vmax,6-8:N int clickCount; int xs,ys; public boolean mouseDown(Event e, int x, int y){ if((y-=yOffset)<0)return false; clickCount=e.clickCount; if(e.modifiers==Event.META_MASK){//"Right Click, "; rightClick=true; running=!running; car.running=running; repaint(); }else{ rightClick=false; changed=null; if(x for(int i=0;i if(carNmax.inside(x,y)){ mode=i; changed=carNmax; break; }else if(carVmax.inside(x,y)){ mode=N+i; changed=carVmax; break; //}else if(carN.inside(x,y)){ // mode=2*N+i; // changed=carN; // break; } } if(changed!=null)iField.setEditable(true);//requestFocus(); else iField.setEditable(false); } xs=x; ys=y; return true; } public boolean mouseMove(Event e, int x, int y){ if((y-=yOffset)<0||running)return false; XY.setText("("+x+", "+y+")"); return true; }
public boolean mouseDrag(Event e, int x, int y){ if((y-=yOffset)<0||running)return false; XY.setText("("+(xs-x)+", "+(y-ys)+")"); return true; } /*public boolean mouseUp(Event e, int x, int y){ if((y-=yOffset)<0)return false; return true; }*/ FontMetrics fm; int chy,chy2; int w=10,w2=2*w,dy,dx,dy2,xi,xf; Rectangle carNmax[]=new Rectangle[N]; Rectangle carVmax[]=new Rectangle[N]; //Rectangle carN[]=new Rectangle[N]; Rectangle changed; static int ds=80; void clear(boolean status){ if(g==null){ bgImage = createImage(area.width, area.height); gb = bgImage.getGraphics(); fgImage = createImage(area.width, area.height); g = fgImage.getGraphics(); fm=gb.getFontMetrics(); chy=fm.getHeight(); chy2=chy*2; car.init(g,w,area.width,area.height); dy=area.height/N; dy2=dy-w2; dx=area.width-4*w; yy=0; xi=w+1; xf=area.width-w; int dd=dy2+xi; for(int i=0;i /* R=new Rectangle(xf,yy,xi,w); R2=new Rectangle(xf,yy+dd,xi,w); L=new Rectangle(0,yy+dd,xi,w); L2=new Rectangle(0,yy,xi,w);*/ carNmax=new Rectangle(xx=car.xi2,yy=car.yi2+chy,ds,chy); //carN=new Rectangle(xx+ds,yy,ds,chy); carVmax=new Rectangle(xx,yy+chy,ds,chy); } }else if(status)car.init(g,w,area.width,area.height); gb.setColor(bgColor); gb.fillRect(0, 0, area.width, area.height); gb.setColor(Color.black); gb.drawLine(0,0,area.width-1,0); gb.drawRect(0,area.height-1,area.width-1,area.height-1); yy=w; for(int i=0;i gb.drawRect(0,yy,w,dy2); gb.drawRect(w2,yy,dx,dy2); gb.drawRect(area.width-w,yy,w,dy2); c=new car(i,0); car.top=c; car.loop=false; } gb.setColor(cstop); /* for(int i=0;i Rs=true; Ls=true; drawRect(gb,R); drawRect(gb,L); }*/ gb.setColor(Color.gray); yy-=(dy+w); int yy2=yy-dy; for(int i=0;i gb.drawLine(i,yy,i+w,yy); gb.drawLine(i,yy2,i+w,yy2); } } // void drawRect(Graphics g,Rectangle r){ // g.fillOval(r.x,r.y,r.width,r.height); // } public void paint(Graphics gs){ update(gs); } public void update(Graphics gs){ g.drawImage(bgImage, 0, 0, this); g.drawString(STR[1]+d2String(time),area.width/2,25); for(int i=0;i.draw(); if(changed!=null){ g.setColor(Color.white); if(clickCount==2){ int dh; if(mode for(int i=0;i g.fillRect(changed.x,carNmax.y+dh,changed.width,changed.height); } } else g.fillRect(changed.x,changed.y,changed.width,changed.height); } g.setColor(Color.gray); for(int i=0;i g.drawString("Nmax="+car.maxCount,xx=carNmax.x,yy=carNmax.y+chy); g.drawString("N="+car.count,xx+ds,yy); g.drawString("Vmax="+car.vmax,xx,yy+=chy); g.drawString("n="+car.passed,xx+ds,yy); } // drawing work gs.drawImage(fgImage, 0, yOffset, this); } }
class car extends rk4{ static int N=3,size,size2,size3,size0; static int xmax,xmin,dy2; static double ai=10.,vmax[]={20.,30.,40.}; // reaction time set to 1.0 sec static double reactionTime=0.5,dmin[]=new double[N] ,dmin2[]=new double[N],dmax[]=new double[N]; static int xi,xf,yi[]=new int[N],yf[]=new int[N]; static int xi2,xf2,xi3,xf3,yi2[]=new int[N],yf2[]=new int[N]; static int maxCount[]={20,20,20},count[]={0,0,0},passed[]={0,0,0}; static car top[]=new car[3]; static boolean loop[]={false,false,false}; static double delta; static car tmp=null; static Graphics g; //static boolean lastTurn=false; int mode=0;// right,down,left,up boolean turn=false; boolean gone=false; static boolean debug=false,running=true; int X,Y,id; double a; car next=null; double accelerated=1.,sign=1.; //static int width=8,height=5; car(int idi,int modei){ init(2,true);// 1D motion id=idi; mode=modei; y[1]=vmax[id]/3.;//*Math.random(); if(mode==0){ Y=yi[id]; y[0]=xmin; a=ai; sign=1.; }else{ mode=2; Y=yf[id]; y[0]=xmax; a=-ai; sign=-1.; y[1]=-y[1]; } count[id]++; gone=false; } static void init(Graphics gi,int w,int width,int height){ int y0=(int)(w/4.+0.5); xmax=width; xmin=0; g=gi; size=w/2; size0=size/2; size2=w; size3=w*3/2; xi=w+size-y0; xf=width-w-size-y0; xi2=xi+size2; xf2=xf-size2; xi3=xi2+size2; xf3=xf2-size2; height/=3; int dy=height-w; dy2=dy/2; running=true; for(int i=0;i yi=y0; yf=yi+dy; yi2=yi+size; yf2=yf-size; setRange(i); count=0; passed=0; } } static void setRange(int i){ dmin=vmax*reactionTime; if(dmin=size2; dmin2=dmin/2.; if(dmin2=size2; dmax=dmin2+size2; } public void derivs(double x,double y[],double dydx[]){ dydx[0]=y[1]; dydx[1]=a; // } void advanced(double dt){ //try{ switch(mode){//處理車子轉彎 case 0://right X=(int)y[0]; if(gone)break;//離開 //if(X>xf3&&y[0]!=0.)y[1]=-ai; //else if(y[0]>xf){ if(this!=top[id]&&next!=null && Math.random()>0.5){//非頭尾則決定是否離開 gone=true; y[1]=vmax[id];//快速通過 //if(next!=null && next.y[1]==0.)next.a=next.sign*ai; }else{//轉彎 y[0]=yi[id]; y[1]=y[1]/2.;// 慢 a=ai; mode++; sign=1.; X=xf; } //if(next!=null )next.turn=true; break; }else if(y[0]>xf2&&next!=null&&next.mode==3)next.turn=true; //if(turn&&X>xf2)y[1]/=2.;//前一個尚在轉彎,慢 if(next!=null&&next.turn){//在轉彎口 if(X>xi2){ next.turn=false;//離開轉彎口 if(next.y[1]==0.)next.a=next.sign*ai; }else if(y[1]==0. && next.mode==3 && next.Y next.y[1]=0.; next.a=0.; } } break; case 1://down if(y[0]>yf[id]){//必然會轉彎 y[0]=xf; a=-ai; mode++; y[1]=-y[1]/2.; Y=yf[id]; sign=-1.; //if(next!=null )next.turn=true; break; }else { Y=(int)y[0]; if(y[0]>yf2[id]&&next!=null&&next.mode==0)next.turn=true; } //if(turn && Y>yf2[id])y[1]/=2.; if(next!=null&&next.turn){//是否前一車仍在轉彎 if(Y>yi2[id]){ next.turn=false; if(next.y[1]==0.)next.a=next.sign*ai; }else if(y[1]==0. &&next.mode==0&& next.X>xf2){//卡住後車暫停 next.y[1]=0.; next.a=0.; } } break; case 2://left X=(int)y[0]; if(gone)break; //if(X //else if(y[0] if(this!=top[id] && next!=null&& Math.random()>0.5){ gone=true; y[1]=-vmax[id]; // if(next==null&&top[id].y[0]==0.]top[id].y[1]=top[id].sign*ai; //if(next!=null && next.y[1]==0.)next.a=next.sign*ai; }else{ y[0]=yf[id]; y[1]/=2.; a=-ai; mode++; sign=-1.; X=xi; } if(next==null)top[id].a=top[id].sign*ai; //if(next!=null)next.turn=true; if(this==top[id])loop[id]=true;//繞一圈 break; }else if(y[0] //if(turn && X if(next!=null&&next.turn){ if(X next.turn=false; if(next.y[1]==0.)next.a=next.sign*ai; }else if(y[1]==0. &&next.mode==1&& next.Y>yf2[id]){ next.y[1]=0.; next.a=0.; } } break; case 3://up if(y[0] y[0]=xi; a=ai; mode=0; sign=1.; y[1]=-y[1]/2.; Y=yi[id]; //if(next!=null )next.turn=true; break; }else{ Y=(int)y[0]; if(y[0] } //if(turn && Y if(next!=null&&next.turn){ if(Y next.turn=false; if(next.y[1]==0.)next.a=next.sign*ai; }else if(y[1]==0. &&next.mode==2 && next.X next.y[1]=0.; next.a=0.; } } if(next==null&&turn&&top[id].y[1]==0.) top[id].a=top[id].sign*ai; break; } //} catch (NullPointerException e){ } /* if(gone){ y[0]+=y[1]*dt; if(next!=null){ next.a=sign*ai; next.advanced(dt); }else { top[id].a=sign*ai; } return; }*/ //if(y[1]==0.)a=0.; //等新車 if(count[id] y[0]=yi2[id]+dmin2[id]; y[1]=0.; a=0.; }else if(a!=0.){ nextmove(dt); if(Math.abs(y[1])>vmax[id]){//達到最高速維持等速度運動 y[1]=sign*vmax[id]; a=0.; } } else y[0]+=y[1]*dt;//等速度運動 if(y[1]*sign<0.){//反向運動則停止 y[1]=0.; a=0.; } if(next!=null){//非最後一輛 if(next.gone){//不理會離開車輛 next.a=sign*ai; }else if(next.mode==mode){//同一車道 delta=sign*(y[0]-next.y[0]);//距離 if(delta>dmax[id])next.accelerated=1.0; // 太遠 else if(Math.abs(delta) next.y[1]=0.; next.accelerated=0.; }else if(sign*(next.y[1]-y[1])>0.)next.accelerated=-1.; if(Math.abs(next.y[1]) next.a=next.sign*ai*next.accelerated; //if(next.a!=0&&next.y[1]==0.)next.y[1]=sign*0.1; }else{//速度太快 next.a=0.; //next.y[1]=next.sign*vmax[id]; } }//else {//不同車道 // if(next.y[1]==0.&& (mode-next.mode>1. || !next.turn)) next.a=next.sign*ai; else if(Math.abs(next.X-X)+Math.abs(next.Y-Y) next.y[1]=0.; next.a=0.; } //} next.advanced(dt); if(next.X>xmax || next.X<0.){ next=next.next; count[id]--; passed[id]++; } /* if(loop[id] && count[id] if(mode==2 && X next.a=0.; next.y[1]/=2.; next.turn=true; tmp=new car(id,2); tmp.next=next; next=tmp; //}else if(mode==0 &&X>xi2){ // next.a=0.; // next.y[1]/=2.; // next.turn=true; // tmp=new car(id,0); // tmp.next=next; // next=tmp; } }*/ }else{ // last car if(loop[id]&&top[id].mode==mode){//繞過一圈後 同軌道 delta=sign*(y[0]-top[id].y[0]); if(delta>dmax[id])top[id].accelerated=1.; else if(Math.abs(delta) top[id].y[1]=0.; top[id].accelerated=0.; }else if(sign*(y[1]-top[id].y[1])>0.)top[id].accelerated=-1.; if(Math.abs(top[id].y[1]) top[id].a=top[id].sign*ai*top[id].accelerated; //if(top[id].a!=0.&&top[id].y[1]==0.)top[id].y[1]=0.1*sign; } /*/if(y[1]==0. && top[id].y[1]==0.)top[id].a=sign*ai;/*else{//速度太快 top[id].a=0.; top[id].y[1]=sign*vmax[id]; }*/ }else if(mode!=0 && top[id].y[1]==0.){//不同軌道 //if(mode!=0 || X>xi2) top[id].a=top[id].sign*ai; } if( count[id] //if( (mode!=0 && top[id].mode>mode) || X>xi2 && (top[id].mode!=3 || top[id].y[0]==yi2[id]+dmin2[id])&& // (!loop[id] || top[id].mode>mode && top[id].y[0]>yi[id] || top[id].y[1]==0. ) ) if( top[id].mode>mode ||!loop[id]) { if(X>xi2)next=new car(id,0); }else if(top[id].mode==mode){ if(sign*(top[id].y[0]-y[0])>0)next=new car(id,0); } }else if(top[id].y[1]==0.){//不同軌道 if(mode!=0 || X>xi2) top[id].a=top[id].sign*ai; } } } static int xx,yy; void draw(){ //g.drawRect(X,Y,5,5); if(a==0.){ if(y[1]!=0.)g.setColor(Color.green); else g.setColor(Color.gray); }else if(sign*a>0.)g.setColor(Color.blue); else g.setColor(Color.red); if(debug&&this==top[id])g.fillRect(X,Y,size,size); else g.drawRect(X,Y,size,size); if(!running){ g.setColor(Color.red); if(mode%2==0)g.drawLine(xx=X+size0,yy=Y+size0,xx,yy+(int)y[1]); else g.drawLine(xx=X+size0,yy=Y+size0,xx-(int)y[1],yy); } if(next!=null)next.draw(); } }
|