public static Vector2D operator *(Vector2D lhs, double rhs) { Vector2D result = new Vector2D(lhs); result.x *= rhs; result.y *= rhs; return result; }
public Wall2D(Vector2D vectorFrom, Vector2D vectorTo) { _vectorFrom = vectorFrom; _vectorTo = vectorTo; calculateNormal(); }
public static Vector2D operator *(double lhs, Vector2D rhs) { Vector2D result = new Vector2D(rhs); result.x *= lhs; result.y *= lhs; return result; }
public static Vector2D operator /(double lhs, Vector2D rhs) { Vector2D returnVal = new Vector2D(); returnVal.X = lhs / rhs.X; returnVal.Y = lhs / rhs.Y; return returnVal; }
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; }
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; }
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); }
/// <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; }
public static Vector2D operator /(Vector2D lhs, double val) { Vector2D result = new Vector2D(lhs); result.x /= val; result.y /= val; return result; }
public static Vector2D operator -(Vector2D lhs, Vector2D rhs) { Vector2D result = new Vector2D(lhs); result.x -= rhs.x; result.y -= rhs.y; return result; }
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); }
public SoccerGoal(Vector2D leftPost, Vector2D rightPost, Vector2D facing) { _leftPost = leftPost; _rightPost = rightPost; _facingDirection = facing; _goalsScored = 0; _goalLineCenter = (_leftPost + _rightPost) / 2.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); }
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; }
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; }
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))); } }
//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; }
public bool IsPositionInside(Vector2D position) { return IsPositionInside(position, RegionModifier.Normal); }
//------------------------- 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; }