CS010 Introduction to Computer Science I
Term Project
Deliverable Two


Swarm and Flocking Behavior:
Neighbors and Iterative Refinement
(last updated 11/13/2007)

For the second deliverable, you will implement the elements of actual swarm behavior.  Swarming or flocking behavior relies on a population of identical critters that are aware of and respond to other critters in their respective neighborhoods.  Each critter steers left or right or accelerates or slows down based on the collective behaviors of its neighbors.  For this second deliverable, we will define neighborhoods for critters and the features over neighborhoods that will be needed to determine the appropriate steering adjustments that give rise to swarming.  After reading the descriptions below, you may want to come back and read the sections on Separation, Cohesion and Alignment from this paper.

In addition, we will refine our representation of a critter.  Also, since we are anticipating critters of different types (e.g., different types of birds), your critter data type should include fields type and color (both of which should be symbols).  In order to have everyone on the same page, use the structure definition: (define-struct critter (loc vel type color)) where location and velocity are posns and type and color are symbols.

Neighbors.  The neighbors of a particular critter make up a sub-set of the critters from the total swarm that are close-enough to the critter in question.  (Note, this subset is still technically a swarm -- a list of critters.)  You should define a parameter NEIGHBOR-RADIUS that defines a circle (centered on the given critter's current location), within which critters are considered to be close-enough (i.e., considered to be a neighbor).  In addition, you should define a parameter FIELD-OF-VIEW as an angle (in radians) that defines how much of the circle is perceived by the critter.  The angle is a deflection, left and right, from the critters current heading.  Essentially, critters within the wedge of the circle directly behind the critter are not observed and should be ignored when considering neighbors.

Based on a set of neighbors for a given critter, we will want to implement three behaviors: separation, cohesion, and alignment.  Critters should avoid bumping into neighbors, essentially maintaining a "personal space" separation around each critter.  At the same time, critters want to stay close to the other critters so as to travel in a cohesive group.  In order to travel together in the group, the critters want to align their speed and heading with their neighbors.

Each of the three behaviors -- separation, cohesion and alignment -- will be implemented by computing steering adjustment vectors that will be employed during each critter's update.  That is, in your first deliverable you updated a critter's position by adding the velocity vector.  Now, critters' velocity vectors will be updated by adjustments based on the three behaviors.  This resulting velocity will be used to update the critter's position as before.

Separation.  In order to implement separation, we will need to find the position offset (not just distance, but directional distance) from the given critter for each critter in the neighborhood.  These vectors act as repelling forces and are scaled by the inverse-squares of the plain distance to each respective critter.  Thus, a neighbor that is close to the critter will have a stronger repelling force than one that is just inside the NEIGHBOR-RADIUS.  Given all the repelling forces for each critter in the neighborhood, the vectors are combined (summed) into a single separation steering vector. 

Cohesion.  In order to implement cohesion, we find the average position for all critters in the neighborhood.  This position is in some sense the place this critter wants to be.  To generate a cohesion steering vector, we subtract our critter's current location from the desired location (i.e., the average location we found first).

Alignment.  To implement alignment, we simply find the average velocity vector of all neighbors.  This average is the desired (for the purposes of alignment) velocity vector.  To generate an alignment steering vector, we subtract our critter's current velocity vector from the desired vector (i.e., the average we found first). 

Edge-avoidance.  Although we implemented our update such that critters flying off one edge reappear at the other, we want critters to avoid going off the edge. Thus, you will also implement an edge avoidance steering vector. Edge avoidance steering will be similar to separation above. If an edge is "visible" within the neighborhood, the edge-avoidance steering adjustment should produce a vector pointing away from the edge with a magnitude based on the inverse square of the distance to the edge.

Nominal-speed.  Your critters have an innate drive to travel at a particular nominal speed.  They will deviate from this in order avoid edges, align with other critters, etc.  But there is always a push to go faster if they are currently moving slower than their nominal speed.  Similarly, if they are traveling faster than their nominal speed (say, perhaps because of cohesion) then there is a contributing factor that wants to slow the critter down.

For this week's project deliverable, you should (minimally) write the functions:
get-neighbors: critter swarm -> swarm,
get-separation-vector: critter swarm -> posn
get-cohesion-vector: critter swarm -> posn
get-alignment-vector: critter swarm -> posn
get-edge-avoidance-vector: critter -> posn
and get-nominal-speed-vector: critter -> posn
where posns are used to represent the vectors of interest and where the lists of critters naturally are the collections of neighbors found by get-neighbors with a critter and the full swarm.
 
In order to implement the swarming required for this deliverable, you will need to update your update function so that it takes into account the four steering vectors and the nominal speed vector produced for the three behaviors plus the edge avoidance and speed maintenance.

To grade this deliverable, I will review your code (including contracts, purpose statements, indentation, etc.) and I will run the four functions with my own swarm.  It is important that you follow the instructions carefully. Remember to include the acknowledgment template at the top of your file.