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
        }
Ejemplo n.º 2
0
 ///<summary>
 ///Add an agent to the flock
 ///</summary>
 ///<param name="newAgent">The agent to add</param>
 public void AddAgent(Agent newAgent)
 {
     if (boids.Count <= MAX_BOIDS)
     {
         boids.Add(newAgent);
     }
 }
        /* Seperation
         * Steer away from our neighbors to distance given agent from peers.
         *
         * We assume that neighbors represents all of the visible neighbors of the
         * provided agent.
         */
        private static Vector2 ComputeSeperation(Agent agent, List<Flockable> neighbors)
        {
            Vector2 steeringForce = new Vector2();
            int numNeighbors = 0;

            foreach (Flockable otherAgent in neighbors)
            {
                if (otherAgent.Equals(agent) == false)
                {
                    Vector stupidTemp = DotNET.Point.Subtract(agent.getLocation(), otherAgent.getLocation());
                    Vector2 diffBetweenAgents = new Vector2((float) stupidTemp.X, (float) stupidTemp.Y);

                    diffBetweenAgents.Normalize();
                    diffBetweenAgents = Vector2.Divide(diffBetweenAgents, diffBetweenAgents.Length());

                    steeringForce = Vector2.Add(steeringForce, diffBetweenAgents);

                    numNeighbors += 1;
                }
            }

            return steeringForce;
        }
        /* 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();
        }
        /* 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;
        }
        public static Vector2 Seek(Agent agent, Vector2 goal)
        {
            Vector2 agentLocation = new Vector2((float) agent.getLocation().X, (float) agent.getLocation().Y);
            Vector2 desired = Vector2.Subtract(goal, agentLocation);

            desired.Normalize();

            return desired;
        }
        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;
        }