复制代码
- //:FieldOBeasts.java
- //Demonstrationofcomplexitytheory;simulates
- //herdingbehaviorinanimals.Adaptedfrom
- //aprogrambyLarryOBrienlobrien@msn.com
- importjava.awt.*;
- importjava.awt.event.*;
- importjava.applet.*;
- importjava.util.*;
- classBeast{
- int
- x,y,//Screenposition
- currentSpeed;//Pixelspersecond
- floatcurrentDirection;//Radians
- Colorcolor;//Fillcolor
- FieldOBeastsfield;//WheretheBeastroams
- staticfinalintGSIZE=10;//Graphicsize
- publicBeast(FieldOBeastsf,intx,inty,
- floatcD,intcS,Colorc){
- field=f;
- this.x=x;
- this.y=y;
- currentDirection=cD;
- currentSpeed=cS;
- color=c;
- }
- publicvoidstep(){
- //Youmovebasedonthosewithinyoursight:
- Vectorseen=field.beastListInSector(this);
- //Ifyourenotoutinfront
- if(seen.size()>0){
- //Gatherdataonthoseyousee
- inttotalSpeed=0;
- floattotalBearing=0.0f;
- floatdistanceToNearest=100000.0f;
- BeastnearestBeast=
- (Beast)seen.elementAt(0);
- Enumeratione=seen.elements();
- while(e.hasMoreElements()){
- BeastaBeast=(Beast)e.nextElement();
- totalSpeed+=aBeast.currentSpeed;
- floatbearing=
- aBeast.bearingFromPointAlongAxis(
- x,y,currentDirection);
- totalBearing+=bearing;
- floatdistanceToBeast=
- aBeast.distanceFromPoint(x,y);
- if(distanceToBeast<distanceToNearest){
- nearestBeast=aBeast;
- distanceToNearest=distanceToBeast;
- }
- }
- //Rule1:Matchaveragespeedofthose
- //inthelist:
- currentSpeed=totalSpeed/seen.size();
- //Rule2:Movetowardstheperceived
- //centerofgravityoftheherd:
- currentDirection=
- totalBearing/seen.size();
- //Rule3:Maintainaminimumdistance
- //fromthosearoundyou:
- if(distanceToNearest<=
- field.minimumDistance){
- currentDirection=
- nearestBeast.currentDirection;
- currentSpeed=nearestBeast.currentSpeed;
- if(currentSpeed>field.maxSpeed){
- currentSpeed=field.maxSpeed;
- }
- }
- }
- else{//Youareinfront,soslowdown
- currentSpeed=
- (int)(currentSpeed*field.decayRate);
- }
- //Makethebeastmove:
- x+=(int)(Math.cos(currentDirection)
- *currentSpeed);
- y+=(int)(Math.sin(currentDirection)
- *currentSpeed);
- x%=field.xExtent;
- y%=field.yExtent;
- if(x<0)
- x+=field.xExtent;
- if(y<0)
- y+=field.yExtent;
- }
- publicfloatbearingFromPointAlongAxis(
- intoriginX,intoriginY,floataxis){
- //ReturnsbearingangleofthecurrentBeast
- //intheworldcoordiantesystem
- try{
- doublebearingInRadians=
- Math.atan(
- (this.y-originY)/
- (this.x-originX));
- //Inversetanhastwosolutions,soyou
- //havetocorrectforotherquarters:
- if(x<originX){
- if(y<originY){
- bearingInRadians+=-(float)Math.PI;
- }
- else{
- bearingInRadians=
- (float)Math.PI-bearingInRadians;
- }
- }
- //Justsubtracttheaxis(inradians):
- return(float)(axis-bearingInRadians);
- }catch(ArithmeticExceptionaE){
- //Divideby0errorpossibleonthis
- if(x>originX){
- return0;
- }
- else
- return(float)Math.PI;
- }
- }
- publicfloatdistanceFromPoint(intx1,inty1){
- return(float)Math.sqrt(
- Math.pow(x1-x,2)+
- Math.pow(y1-y,2));
- }
- publicPointposition(){
- returnnewPoint(x,y);
- }
- //Beastsknowhowtodrawthemselves:
- publicvoiddraw(Graphicsg){
- g.setColor(color);
- intdirectionInDegrees=(int)(
- (currentDirection*360)/(2*Math.PI));
- intstartAngle=directionInDegrees-
- FieldOBeasts.halfFieldOfView;
- intendAngle=90;
- g.fillArc(x,y,GSIZE,GSIZE,
- startAngle,endAngle);
- }
- }
- publicclassFieldOBeastsextendsApplet
- implementsRunnable{
- privateVectorbeasts;
- staticfloat
- fieldOfView=
- (float)(Math.PI/4),//Inradians
- //Deceleration%persecond:
- decayRate=1.0f,
- minimumDistance=10f;//Inpixels
- staticint
- halfFieldOfView=(int)(
- (fieldOfView*360)/(2*Math.PI)),
- xExtent=0,
- yExtent=0,
- numBeasts=50,
- maxSpeed=20;//Pixels/second
- booleanuniqueColors=true;
- ThreadthisThread;
- intdelay=25;
- publicvoidinit(){
- if(xExtent==0&&yExtent==0){
- xExtent=Integer.parseInt(
- getParameter("xExtent"));
- yExtent=Integer.parseInt(
- getParameter("yExtent"));
- }
- beasts=
- makeBeastVector(numBeasts,uniqueColors);
- //Nowstartthebeastsa-rovin:
- thisThread=newThread(this);
- thisThread.start();
- }
- publicvoidrun(){
- while(true){
- for(inti=0;i<beasts.size();i++){
- Beastb=(Beast)beasts.elementAt(i);
- b.step();
- }
- try{
- thisThread.sleep(delay);
- }catch(InterruptedExceptionex){}
- repaint();//Otherwiseitwontupdate
- }
- }
- VectormakeBeastVector(
- intquantity,booleanuniqueColors){
- VectornewBeasts=newVector();
- Randomgenerator=newRandom();
- //UsedonlyifuniqueColorsison:
- doublecubeRootOfBeastNumber=
- Math.pow((double)numBeasts,1.0/3.0);
- floatcolorCubeStepSize=
- (float)(1.0/cubeRootOfBeastNumber);
- floatr=0.0f;
- floatg=0.0f;
- floatb=0.0f;
- for(inti=0;i<quantity;i++){
- intx=
- (int)(generator.nextFloat()*xExtent);
- if(x>xExtent-Beast.GSIZE)
- x-=Beast.GSIZE;
- inty=
- (int)(generator.nextFloat()*yExtent);
- if(y>yExtent-Beast.GSIZE)
- y-=Beast.GSIZE;
- floatdirection=(float)(
- generator.nextFloat()*2*Math.PI);
- intspeed=(int)(
- generator.nextFloat()*(float)maxSpeed);
- if(uniqueColors){
- r+=colorCubeStepSize;
- if(r>1.0){
- r-=1.0f;
- g+=colorCubeStepSize;
- if(g>1.0){
- g-=1.0f;
- b+=colorCubeStepSize;
- if(b>1.0)
- b-=1.0f;
- }
- }
- }
- newBeasts.addElement(
- newBeast(this,x,y,direction,speed,
- newColor(r,g,b)));
- }
- returnnewBeasts;
- }
- publicVectorbeastListInSector(Beastviewer){
- Vectoroutput=newVector();
- Enumeratione=beasts.elements();
- BeastaBeast=(Beast)beasts.elementAt(0);
- intcounter=0;
- while(e.hasMoreElements()){
- aBeast=(Beast)e.nextElement();
- if(aBeast!=viewer){
- Pointp=aBeast.position();
- Pointv=viewer.position();
- floatbearing=
- aBeast.bearingFromPointAlongAxis(
- v.x,v.y,viewer.currentDirection);
- if(Math.abs(bearing)<fieldOfView/2)
- output.addElement(aBeast);
- }
- }
- returnoutput;
- }
- publicvoidpaint(Graphicsg){
- Enumeratione=beasts.elements();
- while(e.hasMoreElements()){
- ((Beast)e.nextElement()).draw(g);
- }
- }
- publicstaticvoidmain(String[]args){
- FieldOBeastsfield=newFieldOBeasts();
- field.xExtent=640;
- field.yExtent=480;
- Frameframe=newFrame("FieldOBeasts");
- //Optionallyuseacommand-lineargument
- //forthesleeptime:
- if(args.length>=1)
- field.delay=Integer.parseInt(args[0]);
- frame.addWindowListener(
- newWindowAdapter(){
- publicvoidwindowClosing(WindowEvente){
- System.exit(0);
- }
- });
- frame.add(field,BorderLayout.CENTER);
- frame.setSize(640,480);
- field.init();
- field.start();
- frame.setVisible(true);
- }
- }///:~
复制代码
- <applet
- code=FieldOBeasts
- width=640
- height=480>
- <paramname=xExtentvalue="640">
- <paramname=yExtentvalue="480">
- </applet>
欢迎光临 仓酷云 (http://ckuyun.com/) | Powered by Discuz! X3.2 |