Пример #1
0
 public static Vector2D operator *(Vector2D lhs, double rhs)
 {
     Vector2D result = new Vector2D(lhs);
     result.x *= rhs;
     result.y *= rhs;
     return result;
 }
Пример #2
0
        public Wall2D(Vector2D vectorFrom, Vector2D vectorTo)
        {
            _vectorFrom = vectorFrom;
            _vectorTo = vectorTo;

            calculateNormal();
        }
Пример #3
0
 public static Vector2D operator *(double lhs, Vector2D rhs)
 {
     Vector2D result = new Vector2D(rhs);
     result.x *= lhs;
     result.y *= lhs;
     return result;
 }
Пример #4
0
 public static Vector2D operator /(double lhs, Vector2D rhs)
 {
     Vector2D returnVal = new Vector2D();
     returnVal.X = lhs / rhs.X;
     returnVal.Y = lhs / rhs.Y;
     return returnVal;
 }
Пример #5
0
 public static Vector2D operator *(Vector2D lhs, Vector2D rhs)
 {
     Vector2D returnVal = new Vector2D();
     returnVal.X = lhs.X * rhs.X;
     returnVal.Y = lhs.Y * rhs.Y;
     return returnVal;
 }
Пример #6
0
 public static Vector2D operator /(Vector2D lhs, double rhs)
 {
     Vector2D returnVal = new Vector2D();
     returnVal.X = lhs.X / rhs;
     returnVal.Y = lhs.Y / rhs;
     return returnVal;
 }
        /// <summary>
        ///  This function calculates how much of its max steering force the 
        ///  vehicle has left to apply and then applies that amount of the
        ///  force to add.
        /// </summary>
        /// <param name="steeringForce"></param>
        /// <param name="additionalForce"></param>
        /// <returns></returns>
        protected bool accumulateForce(ref Vector2D steeringForce, Vector2D additionalForce)
        {
            bool accumulated = false;

            //first calculate how much steering force we have left to use
            double magnitudeSoFar = steeringForce.Length;

            double magnitudeRemaining = _player.MaxForce - magnitudeSoFar;

            //return false if there is no more force left to use
            if (magnitudeRemaining <= 0.0) return false;

            //calculate the magnitude of the force we want to add
            double magnitudeToAdd = additionalForce.Length;

            //now calculate how much of the force we can really add  
            if (magnitudeToAdd > magnitudeRemaining)
            {
                magnitudeToAdd = magnitudeRemaining;
            }


            //add it to the steering force
            Vector2D add = (Vector2D.Vec2DNormalize(additionalForce) * magnitudeToAdd);
            steeringForce += add;

            //steeringForce.X += add.X;
            //steeringForce.Y += add.Y;

            accumulated = true;


            return accumulated;
        }
Пример #8
0
        public FieldPlayer(SoccerTeam homeTeam,
                      int homeRegionIndex,
                      State<FieldPlayer> startState,
                      Vector2D heading,
                      Vector2D velocity,
                      double mass,
                      double maxForce,
                      double maxSpeed,
                      double maxTurnRate,
                      double scale,
                      PlayerBase.PlayerRoles role)
            : base(homeTeam, homeRegionIndex, heading, velocity, mass, maxForce, maxSpeed, maxTurnRate, scale, role)
        {
            _stateMachine = new StateMachine<FieldPlayer>(this);

            if (startState != null)
            {
                _stateMachine.CurrentState = _stateMachine.PreviousState = startState;
                _stateMachine.GlobalState = GlobalPlayerState.Instance;
                _stateMachine.CurrentState.Enter(this);
            }

            _steeringBehaviors.Seperation = true;

            //set up the kick regulator
            _kickRegulator = new Regulator(ParameterManager.Instance.PlayerKickFrequency);
        }
Пример #9
0
        /// <summary>
        ///  given a List of 2D vectors, a position and  orientation
        ///  this function transforms the 2D vectors into the object's world space
        /// 
        /// </summary>
        /// <param name="points"></param>
        /// <param name="pos"></param>
        /// <param name="forward"></param>
        /// <param name="side"></param>
        /// <returns></returns>
        public static List<Vector2D> WorldTransform(List<Vector2D> points,
                                         Vector2D pos,
                                         Vector2D forward,
                                         Vector2D side)
        {
            //copy the original vertices into the buffer about to be transformed
            List<Vector2D> TranVector2Ds = new List<Vector2D>();

            // make deep copy of buffer
            for (int pointIndex = 0; pointIndex < points.Count; pointIndex++)
            {
                TranVector2Ds.Add(new Vector2D(points[pointIndex]));
            }

            //create a transformation matrix
            Matrix2D matTransform = new Matrix2D();

            //rotate
            matTransform.Rotate(forward, side);

            //and translate
            matTransform.Translate(pos.X, pos.Y);

            //now transform the object's vertices
            matTransform.TransformVector2Ds(TranVector2Ds);

            return TranVector2Ds;
        }
Пример #10
0
        public static Vector2D operator /(Vector2D lhs, double val)
        {
            Vector2D result = new Vector2D(lhs);
            result.x /= val;
            result.y /= val;

            return result;
        }
Пример #11
0
        public static Vector2D operator -(Vector2D lhs, Vector2D rhs)
        {
            Vector2D result = new Vector2D(lhs);
            result.x -= rhs.x;
            result.y -= rhs.y;

            return result;
        }
Пример #12
0
        public static void DrawCircle(Graphics g, Vector2D location, double radius)
        {
            float x = (float)location.X - (float)radius;
            float y = (float)location.Y - (float)radius;

            g.FillEllipse(_currentBrush, x, y, (float)radius * 2.0f, (float)radius * 2.0f);
            g.DrawEllipse(_currentPen, x, y, (float)radius * 2.0f, (float)radius * 2.0f);
        }
Пример #13
0
        public SoccerGoal(Vector2D leftPost, Vector2D rightPost, Vector2D facing)
        {
            _leftPost = leftPost;
            _rightPost = rightPost;
            _facingDirection = facing;

            _goalsScored = 0;
            _goalLineCenter = (_leftPost + _rightPost) / 2.0;
        }
Пример #14
0
 public GoalKeeper(SoccerTeam homeTeam,
       int homeRegionIndex,
       State<GoalKeeper> startState,
       Vector2D heading,
       Vector2D velocity,
       double mass,
       double maxForce,
       double maxSpeed,
       double maxTurnRate,
       double scale)
     :
     base(homeTeam, homeRegionIndex, heading, velocity, mass, maxForce, maxSpeed, maxTurnRate, scale, PlayerRoles.GoalKeeper)
 {
     _stateMachine = new StateMachine<GoalKeeper>(this);
     _stateMachine.CurrentState = _stateMachine.PreviousState = startState;
     _stateMachine.GlobalState = GlobalKeeperState.Instance;
     _stateMachine.CurrentState.Enter(this);
 }
Пример #15
0
        public PlayerBase(SoccerTeam homeTeam, int homeRegionIndex, Vector2D heading, Vector2D velocity,
                       double mass, double maxForce, double maxSpeed, double maxTurnRate, double scale, PlayerRoles role)
            : base(homeTeam.Pitch.GetRegion(homeRegionIndex).VectorCenter, scale * 10.0, velocity, maxSpeed, heading, mass, new Vector2D(scale, scale), maxTurnRate, maxForce)
        {
            _playerRole = role;
            _team = homeTeam;
            _distanceToBallSquared = double.MaxValue;
            _homeRegionIndex = homeRegionIndex;
            _kickoffRegionIndex = homeRegionIndex;

            Vector2D[] player = new Vector2D[4] { new Vector2D(-3, 8), new Vector2D(3, 10), new Vector2D(3, -10), new Vector2D(-3, -8) };

            for (int vertexIndex = 0; vertexIndex < 4; vertexIndex++)
            {
                _vecPlayerVB.Add(player[vertexIndex]);

                //set the bounding radius to the length of the 
                //greatest extent
                if (Math.Abs(player[vertexIndex].X) > BoundingRadius)
                {
                    BoundingRadius = Math.Abs(player[vertexIndex].X);
                }

                if (Math.Abs(player[vertexIndex].Y) > BoundingRadius)
                {
                    BoundingRadius = Math.Abs(player[vertexIndex].Y);
                }
            }

            //set up the steering behavior class
            _steeringBehaviors = new SteeringBehaviors(this, Ball);

            //a player's start target is its start position (because it's just waiting)
            _steeringBehaviors.Target = _team.Pitch.GetRegion(_homeRegionIndex).VectorCenter;

            AutoList<PlayerBase>.GetAllMembers().Add(this);

            _defaultHomeRegionIndex = _homeRegionIndex;
        }
Пример #16
0
        public bool RotateHeadingToFacePosition(Vector2D target)
        {
            Vector2D delta = target - Position;
            Vector2D toTarget = Vector2D.Vec2DNormalize(delta);

            double dot = _heading.GetDotProduct(toTarget);

            //some compilers lose acurracy so the value is clamped to ensure it
            //remains valid for the acos
            if (dot < -1)
                dot = -1;
            else if (dot > 1)
                dot = 1;

            //first determine the angle between the heading vector and the target
            double angle = Math.Acos(dot);

            //return true if the player is facing the target
            if (angle < .00001) return true;

            //clamp the amount to turn to the max turn rate
            if (angle > _maxTurnRate) angle = _maxTurnRate;

            //The next few lines use a rotation matrix to rotate the player's heading
            //vector accordingly
            Matrix2D rotationMatrix = new Matrix2D();

            //notice how the direction of rotation has to be determined when creating
            //the rotation matrix
            rotationMatrix.Rotate(angle * _heading.Sign(toTarget));
            rotationMatrix.TransformVector2Ds(_heading);
            rotationMatrix.TransformVector2Ds(_velocity);

            //finally recreate m_vSide
            _side = _heading.Perp;

            return false;
        }
        /// <summary>
        ///  Calculates the overall steering force based on the currently active
        ///  steering behaviors. 
        /// </summary>
        /// <returns></returns>
        public Vector2D CalculateSteeringForce()
        {
            //reset the force
            _steeringForce.Zero();

            //this will hold the value of each individual steering force
            _steeringForce = sumForces();

            //make sure the force doesn't exceed the vehicles maximum allowable
            _steeringForce.Truncate(_player.MaxForce);

            return _steeringForce;
        }
        public SteeringBehaviors(PlayerBase player, SoccerBall ball)
        {
            _player = player;
            _ball = ball;

            _separationMultiple = ParameterManager.Instance.SeparationCoefficient;
            _viewDistance = ParameterManager.Instance.ViewDistance;
            _tagged = false;
            _interposeDist = 0.0;
            _behaviorFlags = (int)BehaviorFlags.None;

            _dribbleFeelers = new List<Vector2D>(5);

            for (int i = 0; i < _dribbleFeelers.Count; i++)
            {
                _dribbleFeelers[i] = new Vector2D();
            }
        }
        /// <summary>
        ///  This method calls each active steering behavior and acumulates their
        ///  forces until the max steering force magnitude is reached at which
        ///  time the function returns the steering force accumulated to that 
        ///  point
        /// </summary>
        /// <returns></returns>
        protected Vector2D sumForces()
        {
            Vector2D force = new Vector2D();

            //the soccer players must always tag their neighbors
            findNeighbours();

            if (Seperation)
            {
                force += calculateSeparationVector() * _separationMultiple;

                if (!accumulateForce(ref _steeringForce, force)) return _steeringForce;
            }
            
            if (Seek)
            {
                force += calculateSeekVector(_target);
                if (!accumulateForce(ref _steeringForce, force)) return _steeringForce;
            }

            if (Arrive)
            {
                force += calculateArriveVector(_target, DecelerationState.Fast);
                if (!accumulateForce(ref _steeringForce, force)) return _steeringForce;
            }

            if (Pursuit)
            {
                force += calculatePursuitVector(_ball);

                if (!accumulateForce(ref _steeringForce, force)) return _steeringForce;
            }

            if (InterposeTarget)
            {
                force += calculateInterposeVector(_ball, _target, _interposeDist);

                if (!accumulateForce(ref _steeringForce, force)) return _steeringForce;
            }

            return _steeringForce;
        }
 /// <summary>
 /// Given an opponent and an object position this method returns a 
 ///  force that attempts to position the agent between them
 /// </summary>
 /// <param name="ball"></param>
 /// <param name="target"></param>
 /// <param name="distFromTarget"></param>
 /// <returns></returns>
 protected Vector2D calculateInterposeVector(SoccerBall ball,
                                       Vector2D target,
                                       double distFromTarget)
 {
     return calculateArriveVector(target + Vector2D.Vec2DNormalize(ball.Position - target) * distFromTarget, DecelerationState.Normal);
 }
        /// <summary>
        /// This behavior creates a force that steers the agent towards the 
        //  ball
        /// </summary>
        /// <param name="ball"></param>
        /// <returns></returns>
        protected Vector2D calculatePursuitVector(SoccerBall ball)
        {
            Vector2D toBall = ball.Position - _player.Position;

            //the lookahead time is proportional to the distance between the ball
            //and the pursuer; 
            double lookAheadTime = 0.0;

            if (Math.Abs(ball.Speed) > Geometry.MinPrecision)
            {
                lookAheadTime = toBall.Length / ball.Speed;
            }

            //calculate where the ball will be at this time in the future
            _target = ball.CalculateFuturePosition(lookAheadTime);

            //now seek to the predicted future position of the ball
            return  calculateArriveVector(_target, DecelerationState.Fast);
        }
        /// <summary>
        ///  This behavior is similar to seek but it attempts to arrive at the
        ///  target with a zero velocity
        /// </summary>
        /// <param name="target"></param>
        /// <param name="decel"></param>
        /// <returns></returns>
        protected Vector2D calculateArriveVector(Vector2D target, DecelerationState decel)
        {
            Vector2D toTarget = target - _player.Position;

            //calculate the distance to the target
            double dist = toTarget.Length;

            if (dist > 0.0)
            {
                //because Deceleration is enumerated as an int, this value is required
                //to provide fine tweaking of the deceleration..
                double decelerationTweaker = 0.3;

                //calculate the speed required to reach the target given the desired
                //deceleration
                double speed = dist / ((double)decel * decelerationTweaker);

                //make sure the velocity does not exceed the max
                speed = Math.Min(speed, _player.MaxSpeed);

                //from here proceed just like Seek except we don't need to normalize 
                //the ToTarget vector because we have already gone to the trouble
                //of calculating its length: dist. 
                Vector2D desiredVelocity = toTarget * speed / dist;

                return (desiredVelocity - _player.Velocity);
            }

            return new Vector2D(0, 0);
        }
        /// <summary>
        ///  Given a target, this behavior returns a steering force which will
        ///  allign the agent with the target and move the agent in the desired
        ///  direction
        /// </summary>
        /// <returns></returns>
        protected Vector2D calculateSeekVector(Vector2D target)
        {

            Vector2D desiredVelocity = Vector2D.Vec2DNormalize(target - _player.Position)
                                      * _player.MaxSpeed;

            return (desiredVelocity - _player.Velocity);
        }
        /// <summary>
        /// This calculates a force repelling from the other neighbors
        /// </summary>
        /// <returns></returns>
        protected Vector2D calculateSeparationVector()
        {
            //iterate through all the neighbors and calculate the vector from the
            Vector2D steeringForce = new Vector2D();

            List<PlayerBase> allPlayers = AutoList<PlayerBase>.GetAllMembers();
            for (int playerIndex = 0; playerIndex < allPlayers.Count; playerIndex++)
            {
                //make sure this agent isn't included in the calculations and that
                //the agent is close enough
                if (allPlayers[playerIndex] != _player && allPlayers[playerIndex].SteeringBehaviors.Tagged)
                {
                    Vector2D toAgent = _player.Position - allPlayers[playerIndex].Position;

                    //scale the force inversely proportional to the agents distance  
                    //from its neighbor.
                    if (Math.Abs(toAgent.Length) > double.Epsilon)
                    {
                        steeringForce += Vector2D.Vec2DNormalize(toAgent) / toAgent.Length;
                    }
                }
            }

            return steeringForce;
        }
        public Vector2D DetermineBestSupportingPosition()
        {
            //only update the spots every few frames                              
            if (!_regulator.IsReady /* && _bestSupportingSpot != null */)
            {
                return _bestSupportingSpot.m_vPos;
            }

            //reset the best supporting spot
            _bestSupportingSpot = null;

            double BestScoreSoFar = 0.0;


            for (int spotIndex = 0; spotIndex < _supportSpots.Count; spotIndex++)
            {
                //first remove any previous score. (the score is set to one so that
                //the viewer can see the positions of all the spots if he has the 
                //aids turned on)
                _supportSpots[spotIndex].m_dScore = 1.0;

                //Test 1. is it possible to make a safe pass from the ball's position 
                //to this position?
                if (_team.IsPassSafeFromAllOpponents(_team.ControllingPlayer.Position,
                                                       _supportSpots[spotIndex].m_vPos,
                                                       null,
                                                       ParameterManager.Instance.MaxPassingForce))
                {
                    _supportSpots[spotIndex].m_dScore += ParameterManager.Instance.SpotPassSafeScore;
                }


                Vector2D shotTarget = new Vector2D();

                //Test 2. Determine if a goal can be scored from this position.  
                if (_team.CanShoot(_supportSpots[spotIndex].m_vPos,
                                      ParameterManager.Instance.MaxShootingForce, ref shotTarget))
                {
                    _supportSpots[spotIndex].m_dScore += ParameterManager.Instance.SpotCanScoreFromPositionScore;
                }


                //Test 3. calculate how far this spot is away from the controlling
                //player. The further away, the higher the score. Any distances further
                //away than OptimalDistance pixels do not receive a score.
                if (_team.SupportingPlayer != null)
                {
                    const double OptimalDistance = 200.0;

                    double dist = Vector2D.Vec2DDistance(_team.ControllingPlayer.Position,
                                               _supportSpots[spotIndex].m_vPos);

                    double temp = Math.Abs(OptimalDistance - dist);

                    if (temp < OptimalDistance)
                    {

                        //normalize the distance and add it to the score
                        _supportSpots[spotIndex].m_dScore += ParameterManager.Instance.SpotDistFromControllingPlayerScore *
                                             (OptimalDistance - temp) / OptimalDistance;
                    }
                }

                //check to see if this spot has the highest score so far
                if (_supportSpots[spotIndex].m_dScore > BestScoreSoFar)
                {
                    BestScoreSoFar = _supportSpots[spotIndex].m_dScore;

                    _bestSupportingSpot = _supportSpots[spotIndex];
                }

            }

            return _bestSupportingSpot.m_vPos;
        }
 public SupportSpot(Vector2D pos, double value)
 {
     m_vPos = pos;
     m_dScore = value;
 }
Пример #27
0
        public bool IsPositionInside(Vector2D position, RegionModifier modifier)
        {
            if (modifier == RegionModifier.Normal)
            {
                return ((position.X > _left) && (position.X < _right) &&
                     (position.Y > _top) && (position.Y < _bottom));
            }
            else
            {
                double marginX = Width * 0.25;
                double marginY = Height * 0.25;

                return ((position.X > (_left + marginX)) && (position.X < (_right - marginX)) &&
                     (position.Y > (_top + marginY)) && (position.Y < (_bottom - marginY)));
            }
        }
Пример #28
0
        //applies a 2D transformation matrix to a single Vector2D
        public void TransformVector2Ds(Vector2D vPoint)
        {

            double tempX = (m_Matrix._11 * vPoint.X) + (m_Matrix._21 * vPoint.Y) + (m_Matrix._31);

            double tempY = (m_Matrix._12 * vPoint.X) + (m_Matrix._22 * vPoint.Y) + (m_Matrix._32);

            vPoint.X = tempX;

            vPoint.Y = tempY;
        }
Пример #29
0
 public bool IsPositionInside(Vector2D position)
 {
     return IsPositionInside(position, RegionModifier.Normal);
 }
Пример #30
0
        //------------------------- WithinFieldOfView ---------------------------
        //
        //  returns true if subject is within field of view of this player
        //-----------------------------------------------------------------------
        bool IsPositionInFrontOfPlayer(Vector2D position)
        {
            Vector2D ToSubject = position - Position;

            if (ToSubject.GetDotProduct(Heading) > 0)

                return true;

            else

                return false;
        }