//Cohesion produces a steering force that moves a vehicle toward the center of mass of its neighbors //A sheep running after its flock is demonstrating cohesive behavior. Use this force to keep a group of vehicles together. public static Vector2 Cohesion(ref Vehicle[] allCars, Vehicle me, Vector2 currentPosition, Vector2 velocity, int max_speed, int cohesionRadius) { int j = 0; Vector2 averagePosition = Vector2.Zero; Vector2 distance = Vector2.Zero; for (int i = 0; i < allCars.Length; i++) { distance = Vector2.Subtract(currentPosition, allCars[i].CurrentPosition); if (VectorHelpers.Length(distance) < cohesionRadius && allCars[i] != me) { j++; averagePosition = Vector2.Add(averagePosition, allCars[i].CurrentPosition); } } if (j == 0) { return(Vector2.Zero); } else { averagePosition = averagePosition / j; return(Seek(ref averagePosition, ref currentPosition, ref velocity, max_speed)); } }
//Separation creates a force that steers a vehicle away from those in its neighborhood region. //When applied to a number of vehicles, they will spread out, trying to maximize their distance from every other vehicle public static Vector2 Separation(ref Vehicle[] allCars, Vehicle me, ref Vector2 currentPosition, ref Vector2 velocity, int max_speed) { int j = 0; Vector2 separationForce = new Vector2(0); Vector2 averageDirection = new Vector2(0); Vector2 distance = new Vector2(0); for (int i = 0; i < allCars.Length; i++) { distance = Vector2.Subtract(currentPosition, allCars[i].CurrentPosition); if (VectorHelpers.Length(distance) < 100 && allCars[i] != me) { j++; separationForce += Vector2.Subtract(currentPosition, allCars[i].CurrentPosition); separationForce = Vector2.Normalize(separationForce); separationForce = Vector2.Multiply(separationForce, 1 / .7f); averageDirection = Vector2.Add(averageDirection, separationForce); } } if (j == 0) { return(Vector2.Zero); } else { //averageDirection = averageDirection / j; return(averageDirection); } }
//Alignment attempts to keep a vehicle's heading aligned with its neighbors //The force is calculated by first iterating through all the neighbors and averaging their heading vectors. //This value is the desired heading, so we just subtract the vehicle's heading to get the steering force. public static Vector2 Alignment(ref Vehicle[] allCars, Vehicle me, ref Vector2 currentPosition, ref Vector2 velocity, int max_speed) { int j = 0; Vector2 averageDirection = new Vector2(0); Vector2 distance = new Vector2(0); for (int i = 0; i < allCars.Length; i++) { distance = Vector2.Subtract(currentPosition, allCars[i].CurrentPosition); if (VectorHelpers.Length(distance) < 100 && allCars[i] != me) { j++; averageDirection = Vector2.Add(averageDirection, allCars[i].Velocity); } } if (j == 0) { return(Vector2.Zero); } else { averageDirection = averageDirection / j; return(Vector2.Subtract(averageDirection, velocity)); } }
//Flee is the opposite of seek. Instead of producing a steering force to steer the agent toward a target position, flee creates a force that steers the agent away. public static Vector2 Flee(ref Vector2 targetPosition, ref Vector2 currentPosition, ref Vector2 Velocity, int max_speed, int FOV, int vehicleNo) { if (VectorHelpers.Length(Vector2.Subtract(targetPosition, currentPosition)) > FOV) { return(Vector2.Zero); } Vector2 desired_V = Vector2.Normalize(Vector2.Subtract(currentPosition, targetPosition)) * max_speed; return(Vector2.Subtract(desired_V, Velocity)); }