public static void correctOverlap(Agent agent, List<Flockable> neighbors) { double distSq; double overlap; double newX, newY; foreach (Flockable other in neighbors) { if (other is Agent == true) { Vector2 toOther = new Vector2((float)(other.getLocation().X - agent.getLocation().X), (float)(other.getLocation().Y - agent.getLocation().Y)); distSq = toOther.LengthSquared(); //distSq = (Math.Pow((agent.getLocation().X - other.getLocation().X), 2) + Math.Pow((agent.getLocation().Y - other.getLocation().Y), 2)); overlap = agent.getAgentRadiusSq() + other.getAgentRadiusSq() - distSq; if (agent.Equals(other) == false && overlap >= 0) { double scale = overlap / Math.Sqrt(distSq); Vector2 move = new Vector2((float)(toOther.X * scale), (float)(toOther.Y * scale)); //newX = agent.getLocation().X + (((other.getLocation().X - agent.getLocation().X) / Math.Sqrt(distSq)) * overlap); //newY = agent.getLocation().Y + (((other.getLocation().Y - agent.getLocation().Y) / Math.Sqrt(distSq)) * overlap); newX = agent.getLocation().X + move.X; newY = agent.getLocation().Y + move.Y; agent.setLocation(new DotNET.Point(newX, newY)); } } } // end foreach }
/* Alignment * Align the heading of an agent based on those of its neighbors. The * force is calculated by generating an average heading vector. We then * subtract the agent's heading to get the steering force for the agent. * * We assume that neighbors represents all of the visible neighbors of the * provided agent. */ private static Vector2 ComputeAlignment(Agent agent, List<Flockable> neighbors) { // A running sum of the given agent's neighbors headings. Vector2 headingSum = new Vector2(); int divisor = 0; Vector2 weightedHeading; // For each of the given agents neighbors... foreach (Flockable otherAgent in neighbors) { // Ensure that our agent was not counted among its neighbors. if (agent.Equals(otherAgent) == false) { // Add our neighbors heading to our running sum weightedHeading = Vector2.Multiply(otherAgent.getHeading(), otherAgent.getFlockingWeight()); headingSum = Vector2.Add(headingSum, weightedHeading); // Necessary as we allow our given boid to be included in the neighbors. divisor += otherAgent.getFlockingWeight(); } } // The average of the neighbor headings. // Zero vector in the event that provided agent has no neighbors. Vector2 averageHeading = new Vector2(); if (divisor > 0) // Avoid divide by zero erros. { // Basic math. averageHeading = Vector2.Divide(headingSum, (float) divisor); // Subtract the provided agent's heading to produce the steering force. // If this is puzzling the most effective way to think about this is to draw a // picture of the current heading and the average heading. averageHeading = Vector2.Subtract(averageHeading, agent.getHeading()); } // Return steering force necessary to achieve alignment with peers. return averageHeading; }
/* Cohesion * Calculate center of mass of neighbors. */ private static Vector2 ComputeCohesion(Agent agent, List<Flockable> neighbors) { Vector2 centerMassSum = new Vector2(); float numNeighbors = 0; foreach (Flockable otherAgent in neighbors) { if (agent.Equals(otherAgent) == false) { Vector2 stupidTemp = new Vector2((float) otherAgent.getLocation().X, (float) otherAgent.getLocation().Y); if (otherAgent.getFlockingWeight() > 1) { stupidTemp = Vector2.Multiply(stupidTemp, otherAgent.getFlockingWeight()); numNeighbors += otherAgent.getFlockingWeight(); } else { numNeighbors += 1; } centerMassSum = Vector2.Add(centerMassSum, stupidTemp); } } if (numNeighbors > 0) { centerMassSum = Vector2.Divide(centerMassSum, numNeighbors); return Seek(agent, centerMassSum); } return new Vector2(); }
public static List<Flockable> getNeigbors(Agent agent, List<Flockable> candidates) { List<Flockable> neighbors = new List<Flockable>(); double distSq; foreach (Flockable other in candidates) { distSq = (Math.Pow((agent.getLocation().X - other.getLocation().X), 2) + Math.Pow((agent.getLocation().Y - other.getLocation().Y), 2)); if (other is Hand) { if (distSq < other.getNeighborhoodRadiusSq()) { neighbors.Add(other); } } else if (distSq < other.getNeighborhoodRadiusSq() && agent.Equals(other) == false) { neighbors.Add(other); } } return neighbors; }