public static bool HitInStride(Vector ballStart, Vector playerStart, Vector playerVelocity, double time, out Vector throwVelocity, out Vector catchLocation) { var diff = playerStart.NewAdded(ballStart.NewMinus()); // don't try to hit yourself in stride if (diff.Length == 0) { throwVelocity = default; catchLocation = default; return(false); } catchLocation = playerStart.NewAdded(playerVelocity.NewScaled(time)); var v = HowHardToThrow(catchLocation.NewAdded(ballStart.NewMinus()).Length, time); if (v > Constants.maxThrowPower) { throwVelocity = default; catchLocation = default; return(false); } throwVelocity = catchLocation.NewAdded(ballStart.NewMinus()).NewUnitized().NewScaled(v); return(true); }
public static bool HitInStride(Vector ballStart, Vector playerStart, Vector playerVelocity, out Vector throwVelocity, out Vector catchLocation) { var diff = playerStart.NewAdded(ballStart.NewMinus()); // don't try to hit yourself in stride if (diff.Length == 0) { throwVelocity = default; catchLocation = default; return(false); } var speedAWay = diff.NewUnitized().Dot(playerVelocity); var t1 = HowLongItTakesBallToGo(diff.Length, Constants.maxThrowPower); var t2 = HowLongItTakesBallToGo(diff.Length + speedAWay * t1, Constants.maxThrowPower); var t3 = HowLongItTakesBallToGo(diff.Length + speedAWay * t2, Constants.maxThrowPower); if (t3 == Double.MaxValue) { throwVelocity = default; catchLocation = default; return(false); } catchLocation = playerStart.NewAdded(playerVelocity.NewScaled(t3)); throwVelocity = diff.NewAdded(playerVelocity.NewScaled(t3)).NewUnitized().NewScaled(Constants.maxThrowPower); return(true); }
// how hard do I have to throw it for a player to catch it at a given point //public static Vector RequiredThrow(Vector playerStart, Vector ballStart, Vector target) //{ // var playerTime = HowQuicklyCanAPlayerMove(target.NewAdded(playerStart.NewMinus()).Length); // var speed = HowHardToThrow(target.NewAdded(ballStart.NewMinus()).Length, playerTime); // return target.NewAdded(ballStart.NewMinus()).NewUnitized().NewScaled(speed); //} // assuming the player runs at max speed the whole time // and assuming the ball doesn't have friction public static (double, Vector) IntersectBallTime(Vector start, Vector ballStart, Vector ballVelocity, Vector palyerVelocity, double padding, bool boost = false) { if (ballStart.NewAdded(start.NewMinus()).Length == 0) { return(0, start); } var at = 1.0; while (true) { var dissToBall = ballStart.NewAdded(start.NewMinus()).Length; var ballAt = ballStart; if (ballVelocity.Length > 0) { ballAt = ballStart.NewAdded(ballVelocity.NewUnitized().NewScaled(DistanceBallTravels(ballVelocity.Length, at))); ballAt = new Vector(ballAt.x % (2 * FieldDimensions.Default.xMax), ballAt.y % (2 * FieldDimensions.Default.yMax)); if (ballAt.x < -FieldDimensions.Default.xMax) { ballAt = new Vector((-(ballAt.x + FieldDimensions.Default.xMax)), ballAt.y); } else if (ballAt.x < 0) { ballAt = new Vector(-ballAt.x, ballAt.y); } else if (ballAt.x > FieldDimensions.Default.xMax) { ballAt = new Vector((2 * FieldDimensions.Default.xMax) - ballAt.x, ballAt.y); } if (ballAt.y < -FieldDimensions.Default.yMax) { ballAt = new Vector(ballAt.x, (-(ballAt.y + FieldDimensions.Default.yMax))); } else if (ballAt.y < 0) { ballAt = new Vector(ballAt.x, -ballAt.y); } else if (ballAt.y > FieldDimensions.Default.yMax) { ballAt = new Vector(ballAt.x, (2 * FieldDimensions.Default.yMax) - ballAt.y); } dissToBall = ballAt.NewAdded(start.NewMinus()).Length; } var diff = ballAt.NewAdded(start.NewMinus()); var playerVelocityDot = diff.NewUnitized().Dot(palyerVelocity); var playerStartSpeed = new Vector(0, 0); if (playerVelocityDot > 0) { playerStartSpeed = diff.NewUnitized().NewScaled(playerVelocityDot); } var dissTravelled = DistancePlayerTravels(playerStartSpeed.Length, at) + ((boost ? Constants.speedLimit : 0) * at) + padding;// + HowFarCanIBoost(boost); if (dissToBall > dissTravelled) { at += 1; } else { break; } } //while (true) //{ // var dissToBall = ballStart.NewAdded(start.NewMinus()).Length; // var ballAt = ballStart; // if (ballVelocity.Length > 0) // { // ballAt = ballStart.NewAdded(ballVelocity.NewUnitized().NewScaled(DistanceBallTravels(ballVelocity.Length, at))); // ballAt = new Vector(ballAt.x % (2 * FieldDimensions.Default.xMax), ballAt.y % (2 * FieldDimensions.Default.yMax)); // if (ballAt.x < -FieldDimensions.Default.xMax) // { // ballAt = new Vector((-(ballAt.x + FieldDimensions.Default.xMax)), ballAt.y); // } // else if (ballAt.x < 0) // { // ballAt = new Vector(-ballAt.x, ballAt.y); // } // else if (ballAt.x > FieldDimensions.Default.xMax) // { // ballAt = new Vector((2 * FieldDimensions.Default.xMax) - ballAt.x, ballAt.y); // } // if (ballAt.y < -FieldDimensions.Default.yMax) // { // ballAt = new Vector(ballAt.x, (-(ballAt.y + FieldDimensions.Default.yMax))); // } // else if (ballAt.y < 0) // { // ballAt = new Vector(ballAt.x, -ballAt.y); // } // else if (ballAt.y > FieldDimensions.Default.yMax) // { // ballAt = new Vector(ballAt.x, (2 * FieldDimensions.Default.yMax) - ballAt.y); // } // dissToBall = ballAt.NewAdded(start.NewMinus()).Length; // } // var diff = ballAt.NewAdded(start.NewMinus()); // var playerVelocityDot = diff.NewUnitized().Dot(palyerVelocity); // var playerStartSpeed = new Vector(0, 0); // if (playerVelocityDot > 0) // { // playerStartSpeed = diff.NewUnitized().NewScaled(playerVelocityDot); // } // var dissTravelled = DistancePlayerTravels(playerStartSpeed.Length, at) + ((boost ? Constants.speedLimit : 0) * at) + padding;// + HowFarCanIBoost(boost); // if (dissToBall < dissTravelled) // { // at -= 1; // } // else // { // break; // } //} if (ballVelocity.Length == 0) { return(at, ballStart); } else { return(at, ballStart.NewAdded(ballVelocity.NewUnitized().NewScaled(DistanceBallTravels(ballVelocity.Length, at)))); } }