//------------------------------ Pursuit --------------------------------- // // this behavior creates a force that steers the agent towards the // evader //------------------------------------------------------------------------ public Vector2D Pursuit(MovingEntity evader) { //if the evader is ahead and facing the agent then we can just seek //for the evader's current position. Vector2D ToEvader = evader.Pos - m_parentMovingEntity.Pos; double RelativeHeading = m_parentMovingEntity.Heading().Dot(evader.Heading()); if ((ToEvader.Dot(m_parentMovingEntity.Heading()) > 0) && (RelativeHeading < -0.95)) //acos(0.95)=18 degs { return Seek(evader.Pos); } //Not considered ahead so we predict where the evader will be. //the lookahead time is propotional to the distance between the evader //and the pursuer; and is inversely proportional to the sum of the //agent's velocities double LookAheadTime = ToEvader.Length() / (m_parentMovingEntity.MaxSpeed + evader.Speed()); //now seek to the predicted future position of the evader return Seek(evader.Pos + evader.Velocity * LookAheadTime); }
//----------------------------- Evade ------------------------------------ // // similar to pursuit except the agent Flees from the estimated future // position of the pursuer //------------------------------------------------------------------------ public Vector2D Evade(MovingEntity pursuer) { /* Not necessary to include the check for facing direction this time */ Vector2D ToPursuer = (pursuer.Pos - m_parentMovingEntity.Pos); //uncomment the following two lines to have Evade only consider pursuers //within a 'threat range' double ThreatRange = 100.0; if (ToPursuer.LengthSq() > ThreatRange * ThreatRange) return new Vector2D(0.0, 0.0); //the lookahead time is propotional to the distance between the pursuer //and the pursuer; and is inversely proportional to the sum of the //agents' velocities double LookAheadTime = ToPursuer.Length() / (m_parentMovingEntity.MaxSpeed + pursuer.Speed()); //now flee away from predicted future position of the pursuer return Flee(pursuer.Pos + pursuer.Velocity * LookAheadTime); }
//------------------------- Offset Pursuit ------------------------------- // // Produces a steering force that keeps a vehicle at a specified offset // from a leader vehicle //------------------------------------------------------------------------ public Vector2D OffsetPursuit(MovingEntity leader, Vector2D offset) { //calculate the offset's position in world space Vector2D WorldOffsetPos = Utils.PointToWorldSpace(offset, leader.Heading(), leader.Side(), leader.Pos); Vector2D ToOffset = WorldOffsetPos - m_parentMovingEntity.Pos; //the lookahead time is propotional to the distance between the leader //and the pursuer; and is inversely proportional to the sum of both //agent's velocities double LookAheadTime = ToOffset.Length() / (m_parentMovingEntity.MaxSpeed + leader.Speed()); //now Arrive at the predicted future position of the offset return Arrive(WorldOffsetPos + leader.Velocity * LookAheadTime, (int)Deceleration.fast); }