CS010 Introduction to Computer Science I
Term Project
Deliverable Two

Swarm and Flocking Behavior:
Neighbors and Iterative Refinement
(last updated 4/8/2006)

For the second deliverable, you will start implementing 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.  This week, we will define neighborhoods for critters and the features over neighborhoods that will be needed to determine the appropriate steering adjustments to come.  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.  Our initial representation of critters stored locations as x and y values and velocities as deltas in x and y.  Since we will be frequently processing both the x and y as a unit, we will represent the location as a posn and the velocity as a posn.  Also, since we are anticipating critters of different types (e.g., sheep and sheep dogs), 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 (location velocity 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.  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.  In addition, you should define a parameter FIELD-OF-VIEW as an angel (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 ignored.

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.

Need to explain the steering vectors should give the desired velocity or location when added to current velocity.  (I think.  Check this out with the code and verify.)  Thus, get-cohesion-vector should return a vector that when added to the current velocity would place the critter on the center-of-gravity average location.

Separation.  In order to implement separation, we will need to find the position offset 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 distance to each respective critter.  Thus, a neighbor right next 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.  This 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).

For this week's project deliverable, you should (minimally) write functions:
get-neighbors: critter swarm -> swarm,
get-separation-vector: critter swarm -> posn
get-cohesion-vector: criter swarm -> posn
and get-alignment-vector: critter swarm -> 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.

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.