public static PointToLocalSpace ( |
||
point | ||
AgentHeading | ||
AgentSide | ||
AgentPosition | ||
return |
/// <summary> /// given a line segment AB and a circle position and radius, this function /// determines if there is an intersection and stores the position of the /// closest intersection in the reference IntersectionPoint /// /// returns false if no intersection point is found /// </summary> /// <param name="A"></param> /// <param name="B"></param> /// <param name="pos"></param> /// <param name="radius"></param> /// <param name="IntersectionPoint"></param> /// <returns></returns> public static bool GetLineSegmentCircleClosestIntersectionPoint(Vector2D A, Vector2D B, Vector2D pos, double radius, ref Vector2D IntersectionPoint) { Vector2D toBNorm = Vector2D.Vec2DNormalize(B - A); //move the circle into the local space defined by the vector B-A with origin //at A Vector2D LocalPos = Transformations.PointToLocalSpace(pos, toBNorm, toBNorm.Perp, A); bool ipFound = false; //if the local position + the radius is negative then the circle lays behind //point A so there is no intersection possible. If the local x pos minus the //radius is greater than length A-B then the circle cannot intersect the //line segment if ((LocalPos.X + radius >= 0) && ((LocalPos.X - radius) * (LocalPos.X - radius) <= Vector2D.Vec2DDistanceSq(B, A))) { //if the distance from the x axis to the object's position is less //than its radius then there is a potential intersection. if (Math.Sqrt(LocalPos.Y) < radius) { //now to do a line/circle intersection test. The center of the //circle is represented by A, B. The intersection points are //given by the formulae x = A +/-sqrt(r^2-B^2), y=0. We only //need to look at the smallest positive value of x. double a = LocalPos.X; double b = LocalPos.Y; double ip = a - Math.Sqrt(radius * radius - b * b); if (ip <= 0) { ip = a + Math.Sqrt(radius * radius - b * b); } ipFound = true; IntersectionPoint = A + toBNorm * ip; } } return(ipFound); }
/// <summary> /// test if a pass from 'from' to 'to' can be intercepted by an opposing player /// /// </summary> /// <param name="from"></param> /// <param name="target"></param> /// <param name="receiver"></param> /// <param name="opp"></param> /// <param name="PassingForce"></param> /// <returns></returns> public bool IsPassSafeFromOpponent(Vector2D from, Vector2D target, PlayerBase receiver, PlayerBase opp, double PassingForce) { //move the opponent into local space. Vector2D ToTarget = target - from; Vector2D ToTargetNormalized = Vector2D.Vec2DNormalize(ToTarget); Vector2D LocalPosOpp = Transformations.PointToLocalSpace(opp.Position, ToTargetNormalized, ToTargetNormalized.Perp, from); //if opponent is behind the kicker then pass is considered okay(this is //based on the assumption that the ball is going to be kicked with a //velocity greater than the opponent's max velocity) if (LocalPosOpp.X < 0) { return(true); } //if the opponent is further away than the target we need to consider if //the opponent can reach the position before the receiver. if (Vector2D.Vec2DDistanceSq(from, target) < Vector2D.Vec2DDistanceSq(opp.Position, from)) { if (receiver != null) { if (Vector2D.Vec2DDistanceSq(target, opp.Position) > Vector2D.Vec2DDistanceSq(target, receiver.Position)) { return(true); } else { return(false); } } else { return(true); } } //calculate how long it takes the ball to cover the distance to the //position orthogonal to the opponents position double TimeForBall = Pitch.Ball.CalucateTimeToCoverDistance(new Vector2D(0, 0), new Vector2D(LocalPosOpp.X, 0), PassingForce); //now calculate how far the opponent can run in this time double reach = opp.MaxSpeed * TimeForBall + Pitch.Ball.BoundingRadius + opp.BoundingRadius; //if the distance to the opponent's y position is less than his running //range plus the radius of the ball and the opponents radius then the //ball can be intercepted if (Math.Abs(LocalPosOpp.Y) < reach) { return(false); } return(true); }