Example #1
0
        /// <summary>
        /// Ricochet coordinate calculation
        /// </summary>
        /// <param name="ballCoordinates">Ball Coordinates</param>
        /// <returns>Ricochet Ball Coordinates</returns>
        public BallCoordinates Ricochet(BallCoordinates ballCoordinates)
        {
            try
            {
                Coordinates2D intersectionPoint = FindNearestIntersectionPoint(ballCoordinates);

                //Marks.DrawRicochetMark(Convert.ToInt32(intersectionPoint.X), Convert.ToInt32(intersectionPoint.Y), true);

                DateTime ricocheTime = FindRicochetTime(ballCoordinates, intersectionPoint);

                Vector2D vector = FindIntersectionVector(ballCoordinates.Vector, intersectionPoint);

                BallCoordinates coordinates = new BallCoordinates(
                    Convert.ToInt32(intersectionPoint.X),
                    Convert.ToInt32(intersectionPoint.Y), ricocheTime);
                coordinates.Vector = vector;

                return(coordinates);
            }
            catch (Exception e)
            {
                throw new NotSupportedException(String.Format(
                                                    "[{0}] Failed to find ricochet coordinates. Reason: {1}",
                                                    MethodBase.GetCurrentMethod().Name, e.Message));
            }
        }
Example #2
0
        /// <summary>
        /// Find intersection time based on ball coordinates, timestamp, vector and intersection point.
        /// </summary>
        /// <param name="ballCoordinates">Ball coordinates before intersection with border</param>
        /// <param name="intersection">Intersection with border point</param>
        /// <exception cref="ArgumentOutOfRangeException">Thrown in case calculated intersection time is too big</exception>
        /// <exception cref="NotSupportedException">Thrown in case intersection coordinates undefined.</exception>
        /// <returns>Intersection timestamp</returns>
        public DateTime FindRicochetTime(BallCoordinates ballCoordinates, Coordinates2D intersection)
        {
            VerifyBallCoordinatesAndVectorInput(ballCoordinates);

            if (intersection == null || !intersection.IsDefined)
            {
                throw new NotSupportedException(String.Format("[{0}] Intersection coordinates undefined!", MethodBase.GetCurrentMethod().Name));
            }

            double distance = ballCoordinates.Distance(intersection);
            double velocity = ballCoordinates.Vector.Velocity();
            double deltaT   = distance / velocity;

            return(ballCoordinates.Timestamp + TimeSpan.FromSeconds(deltaT));
        }
Example #3
0
        /// <summary>
        /// Calculate intersection vector from intersection point
        /// </summary>
        /// <param name="vector">Last known vector before intersection</param>
        /// <param name="intersection">Intersection point with border</param>
        /// <exception cref="NotSupportedException">Thrown in case passed intersection point is not on the border</exception>
        /// <returns>Ball Vector after intersection</returns>
        public Vector2D FindIntersectionVector(Vector2D vector, Coordinates2D intersection)
        {
            if (vector == null)
            {
                throw new NotSupportedException(String.Format(
                                                    "[{0}] Vector from Intersection point can not be found because last known vector is NULL",
                                                    MethodBase.GetCurrentMethod().Name));
            }

            if (!vector.IsDefined)
            {
                throw new NotSupportedException(String.Format(
                                                    "[{0}] Vector from Intersection point can not be found because last known vector is undefined",
                                                    MethodBase.GetCurrentMethod().Name));
            }

            if (!intersection.IsDefined)
            {
                throw new NotSupportedException(String.Format(
                                                    "[{0}] Vector from Intersection point can not be found because intersection point is undefined",
                                                    MethodBase.GetCurrentMethod().Name));
            }

            bool   isDirectionChanged = false;
            double x = vector.X * RicochetFactor;
            double y = vector.Y * RicochetFactor;

            if (intersection.Y == MinBorderY || intersection.Y == MaxBorderY)
            {
                y *= (-1);
                isDirectionChanged = true;
            }
            if (intersection.X == MinBorderX || intersection.X == MaxBorderX)
            {
                x *= (-1);
                isDirectionChanged = true;
            }
            if (!isDirectionChanged)
            {
                throw new NotSupportedException(
                          String.Format("[{0}] Intersection point must be on border! Current point is {1}x{2}",
                                        MethodBase.GetCurrentMethod().Name, intersection.X, intersection.Y));
            }

            return(new Vector2D(x, y));
        }
Example #4
0
        /// <summary>
        /// Find nearest intersection point with table borders based on
        /// - given ball coordinates and vector
        /// </summary>
        /// <param name="ballCoordinates">Defined coordinates with defined vector</param>
        /// <returns>Coordinates of intersection with border</returns>
        public Coordinates2D FindNearestIntersectionPoint(BallCoordinates ballCoordinates)
        {
            //verify we can proceed to calculate intersection
            VerifyBallCoordinatesAndVectorInput(ballCoordinates);

            Dictionary <Vector2D, Coordinates2D> borderIntersection = new Dictionary <Vector2D, Coordinates2D>();
            List <Vector2D> vectors = new List <Vector2D>();

            //get line slope
            double m = CalculateLineSlope(ballCoordinates.Vector);

            if (ballCoordinates.Vector.X != 0)
            {
                double yb = CalculateY2OnLine(m, ballCoordinates.X, ballCoordinates.Y, MinBorderX);
                double yc = CalculateY2OnLine(m, ballCoordinates.X, ballCoordinates.Y, MaxBorderX);

                Coordinates2D B  = new Coordinates2D(MinBorderX, yb);
                Vector2D      vB = new Vector2D(B.X - ballCoordinates.X, B.Y - ballCoordinates.Y);
                vectors.Add(vB);
                borderIntersection.Add(vB, B); //B

                Coordinates2D C  = new Coordinates2D(MaxBorderX, yc);
                Vector2D      vC = new Vector2D(C.X - ballCoordinates.X, C.Y - ballCoordinates.Y);
                vectors.Add(vC);
                borderIntersection.Add(vC, C); //C
            }

            if (ballCoordinates.Vector.Y != 0)
            {
                double xa = CalculateX2OnLine(m, ballCoordinates.X, ballCoordinates.Y, MinBorderY);
                double xd = CalculateX2OnLine(m, ballCoordinates.X, ballCoordinates.Y, MaxBorderY);

                Coordinates2D A  = new Coordinates2D(xa, MinBorderY);
                Vector2D      vA = new Vector2D(A.X - ballCoordinates.X, A.Y - ballCoordinates.Y);
                vectors.Add(vA);
                borderIntersection.Add(vA, A); //A

                Coordinates2D D  = new Coordinates2D(xd, MaxBorderY);
                Vector2D      vD = new Vector2D(D.X - ballCoordinates.X, D.Y - ballCoordinates.Y);
                vectors.Add(vD);
                borderIntersection.Add(vD, D); //D
            }


            //remove points from wrong direction
            foreach (Vector2D vector in vectors)
            {
                double direction = vector.ScalarProduct(ballCoordinates.Vector)
                                   / (vector.Velocity() * ballCoordinates.Vector.Velocity());
                if (Math.Round(direction, 0) != 1)
                {
                    borderIntersection.Remove(vector);
                }
            }

            //if no points found => Error, consider adding error rate threshold
            if (borderIntersection.Count < 1)
            {
                Log.Print("No vectors found!", eCategory.Error, LogTag.VECTOR);
            }

            //get nearest point
            Coordinates2D intersectionPoint = null;
            double        minDistance       = MaxBorderX * MaxBorderY;

            foreach (Coordinates2D intersection in borderIntersection.Values)
            {
                double dist = intersection.Distance(ballCoordinates);
                if (dist < minDistance)
                {
                    minDistance       = dist;
                    intersectionPoint = intersection;
                }
            }

            return(intersectionPoint);
        }
Example #5
0
 /// <summary>
 /// Coordinates scalar product
 /// </summary>
 /// <param name="coordA">Coordinate to calculate Scalar Product</param>
 /// <param name="coordB">Coordinate to calculate Scalar Product With</param>
 /// <returns>Scalar Product</returns>
 public static double ScalarProduct(Coordinates2D coordA, Coordinates2D coordB)
 {
     return(coordA.X * coordB.X + coordA.Y * coordB.Y);
 }