1+ class Agent {
2+
3+ constructor ( ) {
4+ this . size = 5 ;
5+ this . perceptionRadius = 100 ;
6+ this . minSeparation = 100 ;
7+ this . boundarySeparation = 60 ;
8+ this . maxAccel = 0.4 ;
9+ this . minVel = 4 ;
10+ this . maxVel = 8 ;
11+
12+ this . position = createVector ( random ( width ) , random ( height ) ) ;
13+ this . velocity = p5 . Vector . random2D ( ) ;
14+ this . velocity . mult ( random ( this . minVel , this . maxVel ) ) ;
15+ this . acceleration = createVector ( 0 , 0 ) ;
16+
17+ }
18+
19+ boundary ( ) {
20+ if ( this . position . x >= width ) {
21+ this . position . x -= width ;
22+ } else if ( this . position . x <= 0 ) {
23+ this . position . x += width ;
24+ }
25+ if ( this . position . y >= height ) {
26+ this . position . y -= height ;
27+ } else if ( this . position . y <= 0 ) {
28+ this . position . y += height ;
29+ }
30+ }
31+
32+ align ( flock ) {
33+ let averageHeading = createVector ( ) ;
34+ let numNeighbours = 0 ;
35+ for ( let neighbour of flock ) {
36+ if ( ! this . position . equals ( neighbour . position ) ) {
37+ if ( this . position . dist ( neighbour . position ) < this . perceptionRadius ) {
38+ numNeighbours += 1 ;
39+ averageHeading . add ( neighbour . velocity ) ;
40+ }
41+ }
42+ }
43+ averageHeading . div ( numNeighbours ) ;
44+ averageHeading . setMag ( this . maxVel ) ;
45+
46+ averageHeading . sub ( this . velocity ) ;
47+
48+ return averageHeading ;
49+ }
50+
51+ cohesion ( flock ) {
52+ let averagePosition = createVector ( ) ;
53+ let numNeighbours = 0 ;
54+ for ( let neighbour of flock ) {
55+ if ( ! this . position . equals ( neighbour . position ) ) {
56+ if ( this . position . dist ( neighbour . position ) < this . perceptionRadius ) {
57+ numNeighbours += 1 ;
58+ averagePosition . add ( neighbour . position ) ;
59+ }
60+ }
61+ }
62+ averagePosition . div ( numNeighbours ) ;
63+ averagePosition . sub ( this . position ) ;
64+ averagePosition . setMag ( this . maxVel ) ;
65+
66+ averagePosition . sub ( this . velocity ) ;
67+
68+ return averagePosition ;
69+ }
70+
71+ separation ( flock ) {
72+ let separationVelocity = createVector ( ) ;
73+ let numNeighbours = 0 ;
74+ for ( let neighbour of flock ) {
75+ if ( ! this . position . equals ( neighbour . position ) ) {
76+ if ( this . position . dist ( neighbour . position ) < this . minSeparation ) {
77+ let tempVel = this . position . copy ( ) ;
78+ tempVel . sub ( neighbour . position ) ;
79+ let tempMag = 1.0 / tempVel . mag ( ) ;
80+ tempVel . setMag ( tempMag ) ;
81+
82+ separationVelocity . add ( tempVel ) ;
83+ numNeighbours += 1 ;
84+ }
85+ }
86+ }
87+ separationVelocity . div ( numNeighbours ) ;
88+ separationVelocity . setMag ( this . maxVel ) ;
89+
90+ separationVelocity . sub ( this . velocity ) ;
91+
92+ return separationVelocity ;
93+ }
94+
95+ minSpeed ( ) {
96+ let heading = createVector ( ) ;
97+ if ( this . velocity . mag ( ) < this . minVel ) {
98+ heading = this . velocity . copy ( ) ;
99+ heading . setMag ( this . maxVel ) ;
100+ heading . sub ( this . velocity ) ;
101+ }
102+ return heading ;
103+ }
104+
105+ avoidBoundary ( ) {
106+ let desiredVel = createVector ( ) ;
107+ if ( this . position . x >= width - this . boundarySeparation && this . velocity . x > 0 ) {
108+ desiredVel = createVector ( - this . velocity . x , this . velocity . y ) ;
109+ desiredVel . setMag ( this . maxVel ) ;
110+ desiredVel . sub ( this . velocity ) ;
111+ } else if ( this . position . x <= this . boundarySeparation && this . velocity . x < 0 ) {
112+ desiredVel = createVector ( - this . velocity . x , this . velocity . y ) ;
113+ desiredVel . setMag ( this . maxVel ) ;
114+ desiredVel . sub ( this . velocity ) ;
115+ }
116+ if ( this . position . y >= height - this . boundarySeparation && this . velocity . y > 0 ) {
117+ desiredVel = createVector ( this . velocity . x , - this . velocity . y ) ;
118+ desiredVel . setMag ( this . maxVel ) ;
119+ desiredVel . sub ( this . velocity ) ;
120+ } else if ( this . position . y <= this . boundarySeparation && this . velocity . y < 0 ) {
121+ desiredVel = createVector ( this . velocity . x , - this . velocity . y ) ;
122+ desiredVel . setMag ( this . maxVel ) ;
123+ desiredVel . sub ( this . velocity ) ;
124+ }
125+
126+ return desiredVel ;
127+ }
128+
129+ flocking ( flock ) {
130+ let alignment = this . align ( flock ) ;
131+ let cohesion = this . cohesion ( flock ) ;
132+ let separation = this . separation ( flock ) ;
133+
134+ alignment . mult ( alignSlider . value ( ) ) ;
135+ cohesion . mult ( cohesionSlider . value ( ) ) ;
136+ separation . mult ( separationSlider . value ( ) ) ;
137+
138+ this . acceleration . add ( alignment ) ;
139+ this . acceleration . add ( cohesion ) ;
140+ this . acceleration . add ( separation ) ;
141+ this . acceleration . add ( this . minSpeed ( ) ) ;
142+ this . acceleration . add ( this . avoidBoundary ( ) ) ;
143+
144+ this . acceleration . limit ( this . maxAccel ) ;
145+ }
146+
147+ update ( ) {
148+ this . position . add ( this . velocity ) ;
149+ this . velocity . add ( this . acceleration ) ;
150+ this . velocity . limit ( this . maxVel ) ;
151+
152+ this . acceleration . mult ( 0 ) ;
153+ this . boundary ( ) ;
154+ }
155+
156+ show ( showPR , showSR , showVV ) {
157+ fill ( 0 ) ;
158+ stroke ( 0 , 0 , 0 ) ;
159+ ellipse ( this . position . x , this . position . y , this . size , this . size ) ;
160+
161+ // Draw Perception Radius
162+ if ( showPR ) {
163+ noFill ( ) ;
164+ stroke ( 100 , 0 , 0 ) ;
165+ ellipse ( this . position . x , this . position . y , 2 * this . perceptionRadius , 2 * this . perceptionRadius ) ;
166+ }
167+
168+ // Draw Separation Radius
169+ if ( showSR ) {
170+ noFill ( ) ;
171+ stroke ( 0 , 0 , 100 ) ;
172+ ellipse ( this . position . x , this . position . y , 2 * this . minSeparation , 2 * this . minSeparation ) ;
173+ }
174+
175+ // Draw Velocity Vector
176+ if ( showVV ) {
177+ stroke ( 0 , 200 , 0 ) ;
178+ if ( this . velocity . mag ( ) < this . minVel ) {
179+ stroke ( 200 , 0 , 0 ) ;
180+ }
181+ let scale = 50 ;
182+ line ( this . position . x , this . position . y , this . position . x + scale * this . velocity . x , this . position . y + scale * this . velocity . y ) ;
183+ }
184+ }
185+ }
0 commit comments