Nadesłany przez Tomasz Lubiński, 20 października 2010 22:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
boids.js:
//BOIDS //(c) 2010 by Tomasz Lubinski //www.algorytm.org var boids = new Array(20); var r = 50.0; var degree = 120.0; var d_min = 20.0; var weigth_v = 0.1; var weigth_d = 0.15; var weigth_min = 0.15; var weigth_p = 0.1; var v_max = 4.0; var width = 600; var height = 400; //calculate new speed and direction function modify_speed_and_direction() { var dist = 0.0; var deg = 0.0; for (i=0; i<boids.length; i++) { boids[i].alg_mean_vx = boids[i].alg_vx; boids[i].alg_mean_vy = boids[i].alg_vy; boids[i].alg_mean_d = 0; boids[i].alg_num = 1; for (j=0; j<boids.length; j++) { if (j==i) continue; dist = Math.sqrt(Math.pow(boids[i].alg_x-boids[j].alg_x,2)+Math.pow(boids[i].alg_y-boids[j].alg_y,2)); deg = Math.acos( boids[i].alg_vx/Math.sqrt(boids[i].alg_vx*boids[i].alg_vx+boids[i].alg_vy*boids[i].alg_vy) * ((boids[j].alg_x-boids[i].alg_x)/dist) + boids[i].alg_vy/Math.sqrt(boids[i].alg_vx*boids[i].alg_vx+boids[i].alg_vy*boids[i].alg_vy) * ((boids[j].alg_y-boids[i].alg_y)/dist)); deg = Math.abs((180*deg)/Math.PI); if (dist < r && deg < degree) { boids[i].alg_num++; boids[i].alg_mean_vx += boids[j].alg_vx; boids[i].alg_mean_vy += boids[j].alg_vy; boids[i].alg_mean_d += dist; } } } for (i=0; i<boids.length; i++) { //adjust speed to neighbours speed boids[i].alg_vx += (weigth_v*((boids[i].alg_mean_vx/boids[i].alg_num)-boids[i].alg_vx)); boids[i].alg_vy += (weigth_v*((boids[i].alg_mean_vy/boids[i].alg_num)-boids[i].alg_vy)); //pertubation boids[i].alg_vx += (weigth_p*((Math.random()-0.5)*v_max)); boids[i].alg_vy += (weigth_p*((Math.random()-0.5)*v_max)); if (boids[i].alg_num > 1) boids[i].alg_mean_d /= (boids[i].alg_num-1); for (j=0; j<boids.length; j++) { if (j==i) continue; dist = Math.sqrt(Math.pow(boids[i].alg_x-boids[j].alg_x,2)+Math.pow(boids[i].alg_y-boids[j].alg_y,2)); deg = Math.acos( boids[i].alg_vx/Math.sqrt(boids[i].alg_vx*boids[i].alg_vx+boids[i].alg_vy*boids[i].alg_vy) * ((boids[j].alg_x-boids[i].alg_x)/dist) + boids[i].alg_vy/Math.sqrt(boids[i].alg_vx*boids[i].alg_vx+boids[i].alg_vy*boids[i].alg_vy) * ((boids[j].alg_y-boids[i].alg_y)/dist)); deg = Math.abs((180*deg)/Math.PI); if (dist < r && deg < degree) { if (Math.abs(boids[j].alg_x-boids[i].alg_x) > d_min) { boids[i].alg_vx += (weigth_d/boids[i].alg_num)*(((boids[j].alg_x-boids[i].alg_x)*(dist-boids[i].alg_mean_d))/dist); boids[i].alg_vy += (weigth_d/boids[i].alg_num)*(((boids[j].alg_y-boids[i].alg_y)*(dist-boids[i].alg_mean_d))/dist); } else //neighbours are too close { boids[i].alg_vx -= (weigth_min/boids[i].alg_num)*((((boids[j].alg_x-boids[i].alg_x)*(d_min))/dist)-(boids[j].alg_x-boids[i].alg_x)); boids[i].alg_vy -= (weigth_min/boids[i].alg_num)*((((boids[j].alg_y-boids[i].alg_y)*(d_min))/dist)-(boids[j].alg_y-boids[i].alg_y)); } } } //check speed is not too high if (Math.sqrt(boids[i].alg_vx*boids[i].alg_vx+boids[i].alg_vy*boids[i].alg_vy)>v_max) { boids[i].alg_vx *= 0.75; boids[i].alg_vy *= 0.75; } } } //move and displat boids function move_and_display() { //first modify speed and direction modify_speed_and_direction(); for (i=0; i<boids.length; i++) { //move boid boids[i].alg_x += boids[i].alg_vx; boids[i].alg_y += boids[i].alg_vy; //check if outside window if (boids[i].alg_x > width) boids[i].alg_x -= width; else if (boids[i].alg_x < 0) boids[i].alg_x += width; if (boids[i].alg_y > height) boids[i].alg_y -= height; else if (boids[i].alg_y < 0) boids[i].alg_y += height; //display new position of boid boids[i].attr({path: "M" + boids[i].alg_x + " " + boids[i].alg_y + "l0 8m0 -1 l-3 -7 l6 0l-3 7"}) if (boids[i].alg_vx < 0) { boids[i].rotate(90.0 + Math.atan(boids[i].alg_vy/boids[i].alg_vx)*180.0/Math.PI, true); } else { boids[i].rotate(-90.0 + Math.atan(boids[i].alg_vy/boids[i].alg_vx)*180.0/Math.PI, true); } } setTimeout("move_and_display()",20); } //initialize data function start() { var paper = Raphael("canvas", width, height); var background = paper.rect(0, 0, width, height); background.attr({fill: "#3490c9"}); paper.text(width - 70, height - 20, "www.algorytm.org"); for (i=0; i<boids.length; i++) { boids[i] = paper.path("M0 0l0 8m0 -1 l-3 -7 l6 0l-3 7"); boids[i].alg_x = Math.floor(Math.random()*width); boids[i].alg_y = Math.floor(Math.random()*height); boids[i].alg_vx = Math.random()*4.0 - 2.0; boids[i].alg_vy = Math.random()*4.0 - 2.0; } setTimeout("move_and_display()",100); }