Boid Algorithm Background
“The Boids and the Bees” project animates multiple small
rectangles (2x2 pixels) on the screen which represent boids
which are programmed to mimic the flocking behavior of animals
in nature. Each boid is initialized by a struct that has a
field for x position, y position, x velocity and y velocity.
In order to create a flock, a fixed length array of boid
structs is initiated. The length of which is the amount
of boids in our flock.
The algorithm which controls flocking behavior
is called the “boid algorithm.” Which states that for
every boid three main rules are checked: separation,
alignment, and cohesion. The separation rule states
that if boids are too close to one another they will
spread out to give the other boids space. The
alignment rule states that boids will change their
speed to mimic surrounding boids. Lastly, the cohesion
rule states that boids will steer towards the center
of mass of the surrounding boids. Although the boids
move in response to others, each boid can only know
of the position of boids within a fixed visual range
just like animals in nature.
The boid algorithm runs for every single boid
in the array one at a time, for reference we will call
this reference boid the main boid. In order to check
these rules, the boid array is looped over and compares
the position and velocity of the main boid to the surrounding boids.
The algorithm accounts for the separation rule
using the following logic. For every other boid, the
xy-position difference between the main boid and the
other boid is computed. If the distance between the two
boids is within the protected range (meaning that the
other boid is too close to the main boid) then a position
vector is calculated pointing the main boid in the
opposite direction of the other boid. During each
iteration of the loop, the position vector is updated
to include the magnitudes of the other close boid neighbors.
After all of the boids have been looped through,
the main boid's velocity is updated using the
accumulated position vector and a scalable avoidance factor.
This moves the boid away from the too close neighboring boids.
Next, the algorithm accounts for the alignment
rule using the following logic. For every other boid,
the algorithm checks to see if the other boid is within
the main boid's visual range (meaning the main boid
can “see” the other boid). If the other boid is
within this visual range, then the other boid's velocity
is placed into an accumulator velocity variable and
the number of neighboring boids is incremented by 1.
During each iteration of the loop, the individual
velocities of the neighboring boids are added to the
velocity accumulator and the number of neighboring
boids is incremented. After all of the other boids
have been looped through, the average velocity of the
neighboring boids is calculated. This value along with
a scalable matching factor are then used to update the
main boid's velocity vector so that it matches the surrounding boids.
Finally, the algorithm accounts for the cohesion rule
using the following logic. For every other boid, the
algorithm checks to see if the other boid is within the
main boid's visual range. If the other boid is within
this visual range, then the other boid's xy-position is
placed into an accumulator position variable and the
number of neighboring boids is incremented by 1. During
each iteration of the loop, the individual positions of
the neighboring boids are added to the position accumulator
and the number of neighboring boids is incremented. After
all of the other boids have been looped through, the average
position of the neighboring boids (the center of mass) is
calculated. This value along with a scalable centering
factor are then used to update the main boid's velocity
vector so that the main boid gently steers itself towards
the other boids in its visible range.
The boid algorithm ties these three sets of
logic together and during each iteration over another
boid it handles all three sets of rules. The cycle repeats with
the next boid in the array until all boids are properly updated.
To prevent the algorithm from infinitely increasing boid velocity,
the max and min speeds are also bound by certain values.
Similar logic is used to keep the boids within the
drawn bounds of the screen. If a boid crosses a boundary,
its velocity will be influenced by a turn factor in the
direction back towards the boundary. Successful implementation
of boid flocking behavior of boids is shown below.