22
33class Boid {
44
5- PVector loc ;
6- PVector vel ;
7- PVector acc ;
5+ PVector location ;
6+ PVector velocity ;
7+ PVector acceleration ;
88 float r;
99 float maxforce; // Maximum steering force
1010 float maxspeed; // Maximum speed
1111
12- Boid (PVector l , float ms , float mf ) {
13- acc = new PVector (0 ,0 );
14- vel = new PVector (random (- 1 ,1 ), random (- 1 ,1 ));
15- loc = l . get( );
12+ Boid (float x , float y ) {
13+ acceleration = new PVector (0 ,0 );
14+ velocity = new PVector (random (- 1 ,1 ),random (- 1 ,1 ));
15+ location = new PVector (x,y );
1616 r = 2.0 ;
17- maxspeed = ms ;
18- maxforce = mf ;
17+ maxspeed = 2 ;
18+ maxforce = 0.03 ;
1919 }
2020
21- void run (ArrayList boids ) {
21+ void run (ArrayList< Boid > boids ) {
2222 flock(boids);
2323 update();
2424 borders();
2525 render();
2626 }
2727
28+ void applyForce (PVector force ) {
29+ // We could add mass here if we want A = F / M
30+ acceleration. add(force);
31+ }
32+
2833 // We accumulate a new acceleration each time based on three rules
29- void flock (ArrayList boids ) {
34+ void flock (ArrayList< Boid > boids ) {
3035 PVector sep = separate(boids); // Separation
3136 PVector ali = align(boids); // Alignment
3237 PVector coh = cohesion(boids); // Cohesion
@@ -35,60 +40,42 @@ class Boid {
3540 ali. mult(1.0 );
3641 coh. mult(1.0 );
3742 // Add the force vectors to acceleration
38- acc . add (sep);
39- acc . add (ali);
40- acc . add (coh);
43+ applyForce (sep);
44+ applyForce (ali);
45+ applyForce (coh);
4146 }
4247
4348 // Method to update location
4449 void update () {
4550 // Update velocity
46- vel . add(acc );
51+ velocity . add(acceleration );
4752 // Limit speed
48- vel . limit(maxspeed);
49- loc . add(vel );
53+ velocity . limit(maxspeed);
54+ location . add(velocity );
5055 // Reset accelertion to 0 each cycle
51- acc. mult(0 );
52- }
53-
54- void seek (PVector target ) {
55- acc. add(steer(target,false ));
56- }
57-
58- void arrive (PVector target ) {
59- acc. add(steer(target,true ));
56+ acceleration. mult(0 );
6057 }
6158
62- // A method that calculates a steering vector towards a target
63- // Takes a second argument, if true, it slows down as it approaches the target
64- PVector steer (PVector target , boolean slowdown ) {
65- PVector steer; // The steering vector
66- PVector desired = PVector . sub(target,loc); // A vector pointing from the location to the target
67- float d = desired. mag(); // Distance from the target is the magnitude of the vector
68- // If the distance is greater than 0, calc steering (otherwise return zero vector)
69- if (d > 0 ) {
70- // Normalize desired
71- desired. normalize();
72- // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
73- if ((slowdown) && (d < 100.0 )) desired. mult(maxspeed* (d/ 100.0 )); // This damping is somewhat arbitrary
74- else desired. mult(maxspeed);
75- // Steering = Desired minus Velocity
76- steer = PVector . sub(desired,vel);
77- steer. limit(maxforce); // Limit to maximum steering force
78- }
79- else {
80- steer = new PVector (0 ,0 );
81- }
59+ // A method that calculates and applies a steering force towards a target
60+ // STEER = DESIRED MINUS VELOCITY
61+ PVector seek (PVector target ) {
62+ PVector desired = PVector . sub(target,location); // A vector pointing from the location to the target
63+ // Normalize desired and scale to maximum speed
64+ desired. normalize();
65+ desired. mult(maxspeed);
66+ // Steering = Desired minus Velocity
67+ PVector steer = PVector . sub(desired,velocity);
68+ steer. limit(maxforce); // Limit to maximum steering force
8269 return steer;
8370 }
84-
71+
8572 void render () {
8673 // Draw a triangle rotated in the direction of velocity
87- float theta = vel . heading2D() + PI / 2 ;
74+ float theta = velocity . heading2D() + radians ( 90 ) ;
8875 fill (200 ,100 );
8976 stroke (255 );
9077 pushMatrix ();
91- translate (loc . x,loc . y);
78+ translate (location . x,location . y);
9279 rotate (theta);
9380 beginShape (TRIANGLES );
9481 vertex (0 , - r* 2 );
@@ -100,26 +87,25 @@ class Boid {
10087
10188 // Wraparound
10289 void borders () {
103- if (loc . x < - r) loc . x = width + r;
104- if (loc . y < - r) loc . y = height + r;
105- if (loc . x > width + r) loc . x = - r;
106- if (loc . y > height + r) loc . y = - r;
90+ if (location . x < - r) location . x = width + r;
91+ if (location . y < - r) location . y = height + r;
92+ if (location . x > width + r) location . x = - r;
93+ if (location . y > height + r) location . y = - r;
10794 }
10895
10996 // Separation
11097 // Method checks for nearby boids and steers away
111- PVector separate (ArrayList boids ) {
112- float desiredseparation = 20.0 ;
98+ PVector separate (ArrayList< Boid > boids ) {
99+ float desiredseparation = 25.0f ;
113100 PVector steer = new PVector (0 ,0 ,0 );
114101 int count = 0 ;
115102 // For every boid in the system, check if it's too close
116- for (int i = 0 ; i < boids. size(); i++ ) {
117- Boid other = (Boid ) boids. get(i);
118- float d = PVector . dist(loc,other. loc);
103+ for (Boid other : boids) {
104+ float d = PVector . dist(location,other. location);
119105 // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
120106 if ((d > 0 ) && (d < desiredseparation)) {
121107 // Calculate vector pointing away from neighbor
122- PVector diff = PVector . sub(loc ,other. loc );
108+ PVector diff = PVector . sub(location ,other. location );
123109 diff. normalize();
124110 diff. div(d); // Weight by distance
125111 steer. add(diff);
@@ -136,60 +122,56 @@ class Boid {
136122 // Implement Reynolds: Steering = Desired - Velocity
137123 steer. normalize();
138124 steer. mult(maxspeed);
139- steer. sub(vel );
125+ steer. sub(velocity );
140126 steer. limit(maxforce);
141127 }
142128 return steer;
143129 }
144130
145131 // Alignment
146132 // For every nearby boid in the system, calculate the average velocity
147- PVector align (ArrayList boids ) {
148- float neighbordist = 25.0 ;
149- PVector steer = new PVector (0 , 0 ,0 );
133+ PVector align (ArrayList< Boid > boids ) {
134+ float neighbordist = 50 ;
135+ PVector sum = new PVector (0 ,0 );
150136 int count = 0 ;
151- for (int i = 0 ; i < boids. size(); i++ ) {
152- Boid other = (Boid ) boids. get(i);
153- float d = PVector . dist(loc,other. loc);
137+ for (Boid other : boids) {
138+ float d = PVector . dist(location,other. location);
154139 if ((d > 0 ) && (d < neighbordist)) {
155- steer . add(other. vel );
140+ sum . add(other. velocity );
156141 count++ ;
157142 }
158143 }
159144 if (count > 0 ) {
160- steer. div((float )count);
161- }
162-
163- // As long as the vector is greater than 0
164- if (steer. mag() > 0 ) {
165- // Implement Reynolds: Steering = Desired - Velocity
166- steer. normalize();
167- steer. mult(maxspeed);
168- steer. sub(vel);
145+ sum. div((float )count);
146+ sum. normalize();
147+ sum. mult(maxspeed);
148+ PVector steer = PVector . sub(sum,velocity);
169149 steer. limit(maxforce);
150+ return steer;
151+ } else {
152+ return new PVector (0 ,0 );
170153 }
171- return steer;
172154 }
173155
174156 // Cohesion
175157 // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
176- PVector cohesion (ArrayList boids ) {
177- float neighbordist = 25.0 ;
158+ PVector cohesion (ArrayList< Boid > boids ) {
159+ float neighbordist = 50 ;
178160 PVector sum = new PVector (0 ,0 ); // Start with empty vector to accumulate all locations
179161 int count = 0 ;
180- for (int i = 0 ; i < boids. size(); i++ ) {
181- Boid other = (Boid ) boids. get(i);
182- float d = loc. dist(other. loc);
162+ for (Boid other : boids) {
163+ float d = PVector . dist(location,other. location);
183164 if ((d > 0 ) && (d < neighbordist)) {
184- sum. add(other. loc ); // Add location
165+ sum. add(other. location ); // Add location
185166 count++ ;
186167 }
187168 }
188169 if (count > 0 ) {
189- sum. div((float )count);
190- return steer(sum,false ); // Steer towards the location
170+ sum. div(count);
171+ return seek(sum); // Steer towards the location
172+ } else {
173+ return new PVector (0 ,0 );
191174 }
192- return sum;
193175 }
194176}
195177
0 commit comments