/// <summary>Run the three primary rules of boidom.</summary> /// <param name="boid">The boid to process.</param> /// <returns>The velocity vector resulting from the three primary rules and their associated weights.</returns> private Vector3D PrimaryRules_1_2_3(Boid boid) { int numNearby = 0; Vector3D summedPosition = new Vector3D(); Vector3D summedVelocity = new Vector3D(); Vector3D summedSeparation = new Vector3D(); // For rule #1, we want the boid to fly towards the center of all of those in its neighborhood. // We find all of those boids, average their positions, and create a velocity vector to move the // boid a bit of the way there. // For rule #2, we want the boid to move away from each other boid it's a bit too close to. // Find all of those boids in its immediate vicinity, and push it away. // For rule #3, we want the boid to match velocities with those boids in its neighborhood. // Sum their velocities, find the average, and move this boid's velocity a bit in that direction. foreach (var other in m_boidModels) { if (other != boid && (other.PreviousPosition - boid.PreviousPosition).Length <= NEIGHBORHOOD_SIZE && boid.ComputeAngle(other) <= 135) { summedPosition += other.PreviousPosition; summedVelocity += other.PreviousVelocity; numNearby++; if ((other.PreviousPosition - boid.PreviousPosition).Length < MIN_DISTANCE_FROM_NEIGHBOR) { summedSeparation -= (other.PreviousPosition - boid.PreviousPosition); } } } var rule1_flyTowardsCenter = (numNearby > 0 ? (summedPosition - boid.PreviousPosition) / numNearby : new Vector3D()) * PERCENTAGE_TO_MOVE_TOWARDS_AVERAGE_POSITION; var rule2_separateFromNearby = summedSeparation; var rule3_matchVelocities = (numNearby > 0 ? (summedVelocity - boid.PreviousVelocity) / numNearby : new Vector3D()) * PERCENTAGE_TO_MOVE_TOWARDS_AVERAGE_VELOCITY; return ((m_rule1Weight * rule1_flyTowardsCenter) + (m_rule2Weight * rule2_separateFromNearby) + (m_rule3Weight * rule3_matchVelocities)); }
/// <summary>Encourage a boid to stay within its aviary.</summary> /// <param name="boid">The boid.</param> /// <returns>The velocity vector encouraging a boid to stay within its bounds.</returns> private Vector3D Rule4_EncourageStayingWithinAviary(Boid boid) { var v = new Vector3D(); // X if (boid.PreviousPosition.X < m_aviary.X) { v.X = m_aviary.X - boid.PreviousPosition.X; } else if (boid.PreviousPosition.X > m_aviary.X + m_aviary.SizeX) { v.X = (m_aviary.X + m_aviary.SizeX) - boid.PreviousPosition.X; } // Y if (boid.PreviousPosition.Y < m_aviary.Y) { v.Y = m_speedLimit; } else if (boid.PreviousPosition.Y > m_aviary.Y + m_aviary.SizeY) { v.Y = (m_aviary.Y + m_aviary.SizeY) - boid.PreviousPosition.Y; } // Z if (boid.PreviousPosition.Z < m_aviary.Z) { v.Z = m_aviary.Z - boid.PreviousPosition.Z; } else if (boid.PreviousPosition.Z > m_aviary.Z + m_aviary.SizeZ) { v.Z = (m_aviary.Z + m_aviary.SizeZ) - boid.PreviousPosition.Z; } return(v * PERCENTAGE_TO_MOVE_TOWARDS_INBOUNDS); }
/// <summary>Encourage a boid to stay close to its home position.</summary> /// <param name="boid">The boid.</param> /// <returns>The velocity vector encouraging a boid to stay at home.</returns> private Vector3D Rule5_TendendcyTowardsHome(Boid boid) { return((m_home - boid.PreviousPosition) * PERCENTAGE_TO_MOVE_TOWARDS_HOME); }