//boidsSimulation.java import java.awt.*; /** * Boids Applet * ボイドもどき * *@version 0.1 29 May 1996 *@author Tasuku Gouda */ public class boidsSimulation extends java.applet.Applet implements Runnable{ int width,height,bestDistance = 30,colorA = 0,colorB = 128; double maxSpeed = 15; double copyWait = 0.5; double centerWait = 0.5; double acceleration = 1.1; int LengthList[][]; Boid ball[]; boolean trail = false,debag = false; Thread t; double tempP_x[]; double tempP_y[]; double angleList[][]; double visibleAngle = Math.PI / 2.0; double lastAngle[]; private Image offScreenImage; private Graphics offScreenGraphics; /** * hypercard では open stack 相当 */ public void init(){ Dimension r = size(); String s; int max = 5; width = r.width; height = r.height; s = getParameter("boids"); if ( s != null ){ max = Integer.parseInt(s); } s = getParameter("max"); if ( s != null ){ maxSpeed = Double.valueOf(s).doubleValue(); } s = getParameter("copyWait"); if ( s != null ){ copyWait = Double.valueOf(s).doubleValue(); } s = getParameter("centerWait"); if ( s != null ){ centerWait = Double.valueOf(s).doubleValue(); } s = getParameter("acceleration"); if ( s != null ){ acceleration = Double.valueOf(s).doubleValue(); } s = getParameter("dist"); if ( s != null ){ bestDistance = (new Integer(s)).intValue(); //System.out.println(bestDistance); } s = getParameter("trail"); if ( s != null ){ trail = Boolean.valueOf(s).booleanValue(); } s = getParameter("debag"); if ( s != null ){ debag = Boolean.valueOf(s).booleanValue(); } s = getParameter("visibleAngle"); if ( s != null ){ visibleAngle = (double)((new Integer(s)).intValue())/2.0 * Math.PI/180.0; } ball = new Boid[max]; LengthList = new int[ball.length][ball.length]; angleList = new double[ball.length][ball.length]; tempP_x = new double[ball.length]; tempP_y = new double[ball.length]; lastAngle = new double[ball.length]; int px1,py1; double speedx,speedy,speed; for(int i = 0;i angle){angle2 = angle2 - angle;}else{angle2 = angle - angle2;} if (dist > bestDistance + 0.5) { if(angle2 < ( Math.PI/2) || angle2 > (Math.PI * 1.5)){ ball[i].speed *= acceleration; }else{ ball[i].speed /= acceleration; } }else if (dist < bestDistance - 0.5) { if(angle2 < (Math.PI/2) || angle2 > (Math.PI * 1.5)){ ball[i].speed /= acceleration; }else{ ball[i].speed *= acceleration; } } if(ball[i].speed > maxSpeed){ ball[i].speed = maxSpeed; }else if (ball[i].speed <= 4){ ball[i].speed = 4; } } for(int i = 0 ; i < ball.length ; i++){ ball[i].vx = tempP_x[i]; ball[i].vy = tempP_y[i]; } } /** *角度を計算 *@param double x *@param double y *@return finded index number */ private double getAngle (double x,double y){ double dist; if (y == 0 && x == 0){ return 0; } /*if (x == 0 && y > 0){ return Math.PI*0.5; }else if (x == 0 && y < 0){ return Math.PI*1.5; }*/ dist = Math.sqrt(Math.pow(x,2) + Math.pow(y,2)); if (y > 0){ return (Math.acos(x/dist)); }else{ return (Math.PI*2-Math.acos(x/dist)); } } /** *一番近くのボイドをさがす *@param index number of me *@return finded index number */ private int whoNear( int n , double angle){ int dist,x = -1; double kx; dist = Integer.MAX_VALUE; for(int i = 0;i < ball.length;i++){ if ( angle > angleList[n][i]){ kx = angle - angleList[n][i]; }else{ kx = angleList[n][i] - angle; } if ( n != i && LengthList[n][i] < dist && ( kx < visibleAngle || kx > (2 * Math.PI - visibleAngle))) { dist = LengthList[n][i]; x = i; } } return x; } /** *ボイド間の距離を返す */ private int getDist(int a,int b){ return LengthList[a][b]; } } /** *ボイド */ class Boid{ int width = 0,height = 0,x = 0,y = 0; double vx,vy,speed = 5; Boid(int width,int height,int locX,int locY,double speedX,double speedY,double speed){ this.width = width; this.height = height; this.speed = speed; x = locX; y = locY; vx = speedX; vy = speedY; } /** *移動 */ public void move(){ x += (int)(vx*speed); y += (int)(vy*speed); if(x >= width ){ x -= width; }else if( x <= 0){ x += width; } if(y >= height){ y -= height; }else if( y <= 0){ y += height; } } } /** *doubleのPoint */ class Dpoint{ double x,y; Dpoint (double x,double y){ this.x = x; this.y = y; } }