This page was automatically generated by NetLogo 4.1. Questions, problems? Contact feedback@ccl.northwestern.edu.
The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Sun's Java site. If the display appear cut off with Firefox, then try another browser (Safari works).
powered by NetLogo
view/download model file: Flock.nlogo
This project is an attempt to simulate the coordinated motion of a group of individuals such as fish in a school, or birds in a flock. Each bird follows a simple rule, and the flock as a whole moves without any leader. A bird adjusts its flight based on the position and/or heading of its three nearest neighbors; this adjustment is partitioned into three zones:
1) Repel range. A bird moves away from neighbors that are too close.
2) Direction range. A bird aligns with neighbors that are a comfortable distance away (i.e., it attempts to match the neighbor's heading.)
3) Position range. A bird moves towards neighbors that are far away.
A bird adjusts its heading towards a vector sum of the "target" headings that these would imply for each neighbor; the influences of birds are weighted by the inverse of distance, such that close birds are more influential than distant ones.
In addition, a bird will accelerate slightly for each neighbor in front of it and in the position range; it will decelerate slightly for each neighbor that is behind it and in the position range. This allows trailing birds to catch up with the flock and leading birds to slow down without turning around. All birds also have a blind spot (the default is 30 degrees) directly behind them, in which they cannot sense the presence of other birds.
For the sake of simplicity, birds reflect off of obstacles as light would reflect off of a mirror. Though this is not necessarily realistic, it adds variety to the simulation by forcing the birds to continually adapt the flocking structure to outside influences.
The RESET_BOARD button erases all obstacles that have been drawn and restores the edge boundary.
The RESET_TURTLES button creates the specified number of birds and places them in black cells on the board.
The GO button executes the flocking rules described above; one button executes a step at a time and the other runs continuously.
The MAKE_OBSTACLES and REMOVE_OBSTACLES buttons allow you to make obstacles that the birds must avoid, and to remove them.
The OBSTACLES_TRANSPARENT and OBSTACLES_OPAQUE buttons toggle the way birds perceive obstacles in the middle of the screen. After selecting obstacles_transparent, birds can still see neighbors that are on the opposite side of an obstruction. Selecting obstacles_opaque (which is done by default in the reset_birds procedure) causes obstacles to block the birds' line of sight and hide neighbors that are behind obstacles. The step by step go button should be used when obstacles are opaque, because no attempt is made to synchronize the turtles' execution of commands when they are looking for obstacles.
The NUMBER slider sets the number of birds in the simulation.
The REPEL_RANGE, DIR_RANGE, and POS_RANGE sliders control the outer limits of each of these zones. The relative sizes must be maintained for the program to function properly (i.e. repel_range < dir_range < pos_range.)
The NOISE slider determines the maximum random adjustment that a bird could make to its heading in a single time step.
The FLEXIBILITY slider controls how completely a bird adjusts its heading to the calculated target. A flexibility of zero would cause a bird to maintain straight-line motion (excluding walls and random turns), while a flexibility of 100 represents instantaneous adjustment to the influences of the three closest neighbors.
Obstacles can easily be created in the center of the screen by using the MAKE_OBSTACLE button; the flock remains quite cohesive when confronted with various shapes and sizes of obstacles. Cohesiveness is affected by the parameters, in particular flexibility and noise.
Modified for NetLogo by B.J. MacLennan, October 2007, from original version by William Thies on Scott Camazine's website.
Based on the Huth and Wissel (1992) model of fish schooling.
globals [w ; width (in degrees) of blind spot behind bird
obstacles_opaque? ; whether or not a bird is unaware of neighbors
; that are hidden behind obstacles
screen-half-width ; one half of world-width
screen-half-height] ; one half of world-height
turtles-own [neighbor_1 neighbor_2 neighbor_3 ; ID number of closest neighbors
distance_1 distance_2 distance_3 ; distance to closest neighbors
target_1 target_2 target_3 ; preferred heading considering each neighbor -alone-
target ; preferred heading considering all three neighbors
i ; counter for selecting neighbors
dist ; distance from a bird to the one in question
acceleration ; extra distance to move forward in a time step
vis_x ; x-counter when testing for obstacles
vis_y ; y-counter when testing for obstalces
vis_x_inc ; increment to vis_x when testing for obstacles
vis_y_inc ; increment to vis_y when testing for obstacles
vis_step] ; number of patches needing to be tested for obstacles
TO RESET_BOARD ;-----------------------------------------------------------------------------------
set screen-half-width floor (world-width / 2)
set screen-half-height floor (world-height / 2)
ask patches [
ifelse ((abs pxcor) = screen-half-width) or ((abs pycor) = screen-half-height)
[set pcolor green] ; colors patches green on edge of screen
[set pcolor black] ; colors all other patches black
]
end
TO RESET_BIRDS ;-----------------------------------------------------------------------------------
set screen-half-width floor (world-width / 2)
set screen-half-height floor (world-height / 2)
set w 30 ; sets width of blind spot
obstacles_opaque ; calls procedure to make obstacles opaque
; to birds
clear-turtles ; kills turtles
crt number ; creates turtles and assigns them random positions
ask turtles [
setxy ((random world-width) - screen-half-width)
((random world-height) - screen-half-height) ; and headings
set heading random 360
set color scale-color red (abs (heading - 180)) 0 180 ; colors turtles according to their headings
repeat 1000
[if pcolor = green ; randomly moves turtles that are in obstacles
[setxy ((random world-width) - screen-half-width)
((random world-height) - screen-half-height)]]
]
end
TO OBSTACLES_TRANSPARENT ;-------------------------------------------------------------------------
set obstacles_opaque? false ; sets "obstacles_opaque?" false
end
TO OBSTACLES_OPAQUE ;------------------------------------------------------------------------------
set obstacles_opaque? true ; sets "obstacles_opaque?" true
end
;;;; TURTLE PROCEDURES ;;;;
TO GO ;--------------------------------------------------------------------------------------------
set i 0 ; initializes variables used in finding neighbors
set distance_1 1000
set distance_2 1000
set distance_3 1000
; (below) determines ID numbers and distances for three closest neighbors; each turtle is
; first checked to be visible (i.e., out of blind spot and in front of obstacles), and then
; its distance is compared with that of neighbor_3. If a bird is closer than neighbor_3,
; it is then compared with neighbor_2 and (if it's closer than neighbor_2) with neighbor_1;
; variables are then re-assigned to accomodate the new neighbor as one of the closest three.
repeat count turtles
[ifelse not ((i = who) or in_blind_spot? or behind_opaque_obstacle?)
[set dist distance turtle i
ifelse dist < distance_3
[ifelse dist < distance_2
[set neighbor_3 neighbor_2
set distance_3 distance_2
ifelse dist < distance_1
[set neighbor_2 neighbor_1
set distance_2 distance_1
set neighbor_1 i
set distance_1 dist]
[set neighbor_2 i
set distance_2 dist
repeat 2 [fd 0]]] ; (see note at end for explanantion of "fd 0")
[set neighbor_3 i
set distance_3 dist
repeat 4 [fd 0]]]
[repeat 6 [fd 0]]]
[repeat 7 [fd 0]]
set i i + 1]
set acceleration 0 ; sets acceleration to zero
set target_1 calc_target neighbor_1 distance_1 ; calculates targets (see procedure below) based on
set target_2 calc_target neighbor_2 distance_2 ; the headings and positions of each neighbor;
set target_3 calc_target neighbor_3 distance_3 ; acceleration is set by the calc_target procedure
; (below) calculates a bird's composite target, weighting each individual target by the inverse
; of distance to that neighbor
set target atan ((sin target_1) * 100 / distance_1 + (sin target_2) * 100 / distance_2 + (sin target_3) * 100 / distance_3)
((cos target_1) * 100 / distance_1 + (cos target_2) * 100 / distance_2 + (cos target_3) * 100 / distance_3)
; (below) turns bird towards target by a fraction specified by "flexibility"; random motion is also
; included to an extent governed by "noise". The "... + 540) mod 360) - 180" clause is necessary to
; ensure that the bird turns in the right direction. For example, if a bird is oriented at 0 degrees
; and its target is 300 degrees, it should consider a 60 [ = ((0 - 300 + 540) mod 360) - 180] degree
; turn to the left instead of a 300 [ = 300 - 0] degree turn to the right.
lt (flexibility / 100 * (((heading - target + 540) mod 360) - 180)) + (random noise) - (random noise)
set color scale-color red (abs (heading - 180)) -60 180 ; colors turtles according to new heading
ifelse (([pcolor] of patch-at dx dy) = green) ; "bounces" birds off of obstacles as light would
[ifelse (([pcolor] of patch-at 0 dy) = green) ; reflect off of a mirror
[set heading 180 - heading
ifelse (([pcolor] of patch-at dx 0) = green)
[set heading 360 - heading]
[fd 0]] ; (see note at end for explanantion of "fd 0")
[fd 0
ifelse (([pcolor] of patch-at dx 0) = green)
[set heading 360 - heading]
[ifelse (abs cos heading) > (abs sin heading)
[set heading 360 - heading]
[set heading 180 - heading]]]]
[repeat 2 [fd 0]]
fd 1 + acceleration ; moves birds forward
end
TO-REPORT CALC_TARGET [the_neighbor the_distance] ;---------------------------------------------------------------
; (below) calculates target by rules described in information window; please see note at end
; for an explanation of "fd 0"
ifelse the_distance < repel_range
[fd 0
report 180 + towards turtle the_neighbor]
[ifelse the_distance < dir_range
[fd 0
report [heading] of turtle the_neighbor]
[ifelse the_distance < pos_range
[ifelse (abs ((((heading - towards turtle the_neighbor) + 540) mod 360) - 180)) < 90
[set acceleration acceleration + 0.3]
[set acceleration acceleration - 0.3]
report towards turtle the_neighbor]
[fd 0
report heading]]]
end
TO MAKE_OBSTACLE
if mouse-down?
[ask patches [
if ((abs (pxcor - mouse-xcor)) < 2) and ((abs (pycor - mouse-ycor)) < 2)
[set pcolor green]]
]
end
TO REMOVE_OBSTACLE
if mouse-down?
[ask patches [
if ((abs (pxcor - mouse-xcor)) < 2) and ((abs (pycor - mouse-ycor)) < 2)
[set pcolor black]
]
]
end
TO-REPORT BEHIND_OPAQUE_OBSTACLE? ;-----------------------------------------------------------------------
if not obstacles_opaque? [report false] ; procedure ends and returns "false" if obstacles
; are not currently opaque
set vis_x ([xcor] of turtle i) - xcor ; sets variables described above
set vis_y ([ycor] of turtle i) - ycor
set vis_step max list abs vis_x abs vis_y
set vis_x_inc vis_x / vis_step
set vis_y_inc vis_y / vis_step
repeat vis_step ; checks the patches between a neighbor and the
[if ([pcolor] of patch-at vis_x vis_y) = black ; bird in question, stopping on a patch that is
[set vis_x vis_x - vis_x_inc ; an obstacle
set vis_y vis_y - vis_y_inc]]
; (below) returns "false" if all patches between
; birds were checked, but returns "true" if the
; checker got stuck on an obstacle between birds
report not (((round vis_x) = 0) and ((round vis_y) = 0))
end
TO-REPORT IN_BLIND_SPOT? ;--------------------------------------------------------------------------------
; (below) compares bird's heading with direction to a neighbor to see if it falls within the
; blind spot
if 0 = distance turtle i [report false]
report (abs ((((heading - towards-nowrap turtle i) + 360) mod 360) - 180)) < (w / 2)
end