generated from pabloqb2000/js-ui_on_canvas_example
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboidsimulation.js
122 lines (108 loc) · 3.04 KB
/
boidsimulation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
class BoidSimulation {
/**
*
* @param n number of initial boids
* @param w width of the simulation
* @param h height of the simulation
* @param obst additional obstacles
*/
constructor(n, w, h, obst) {
this.boids = [];
this.w = w;
this.h = h;
// Default parameters
this.viewR = 25;
this.separation = 0.14;
this.cohesion = 0.12;
this.alignment = 0.05;
this.avoidance = 0.25;
this.maxVel = 1.8;
// Add obstables
this.obstacles = [
new WallObst(0, titleSize*3/1.2),
new WallObst(1, w),
new WallObst(2, h),
new WallObst(3, 0),
new MouseObst(),
];
this.obstacles = this.obstacles.concat(obst);
// Add boids
for(let i = 0; i < n; i++) {
this.newBoid();
}
}
/**
* Adds new boid to the system
*/
newBoid() {
this.boids.push(new Boid(this.randomNewPos(), this));
}
/**
* Returns an available random new position
*/
randomNewPos() {
let p;
do {
p = new Vector([random(this.w), random(this.h)]);
} while(this.obstacles.map(o => o.isIn(p)).reduce((x,y) => x || y));
return p;
}
/**
* First update the cell system
* then update all the boids
*/
update() {
// Create cells
this.cells = Array(ceil(this.h / this.viewR)).fill()
.map(() => Array(ceil(this.w / this.viewR)).fill()
.map(() => Array(0)));
// Fill cells
for(let b of this.boids) {
this.getCell(b).push(b);
}
// Update boids
for(let b of this.boids) {
//b.update(this.boids, this.obstacles);
b.update(this.getNeighbours(b), this.obstacles);
}
}
/**
* Get the cell corresponding to a boid
*/
getCell(b) {
return this.cells[floor(b.pos.getY() / this.viewR)][floor(b.pos.getX() / this.viewR)];
}
/**
* Get the boids in the cell and the neighbour cells of the given boid
*/
getNeighbours(b) {
let i = floor(b.pos.getY() / this.viewR);
let j = floor(b.pos.getX() / this.viewR);
let n = this.cells[i][j];
if(i > 0){
n = n.concat(this.cells[i-1][j]);
if(j > 0) n = n.concat(this.cells[i-1][j-1]);
}
if(j > 0) {
n = n.concat(this.cells[i][j-1]);
if(i < this.cells.length - 1) n = n.concat(this.cells[i+1][j-1])
}
if(i < this.cells.length - 1){
n = n.concat(this.cells[i+1][j]);
if(j < this.cells[0].length - 1) n = n.concat(this.cells[i+1][j+1]);
}
if(j < this.cells[0].length - 1) {
n = n.concat(this.cells[i][j+1]);
if(i > 0) n = n.concat(this.cells[i-1][j+1]);
}
return n;
}
/**
* Draw all boids
*/
draw() {
for(let b of this.boids) {
b.draw();
}
}
}