public static Boolean isCollision(CollisionPoly poly1, CollisionPoly poly2)
        {
            Vector2        direction = new Vector2();
            List <Vector2> simplex   = new List <Vector2>();

            while (true)
            {
                switch (simplex.Count)
                {
                case 0:
                    //direction in the direction of separation
                    direction = Vector2.Subtract(poly1.center(), poly2.center());
                    break;

                case 1:
                    //direction opposite direction of separation
                    direction = Vector2.Multiply(direction, -1);
                    break;

                case 2:
                    //direction orthogonal to the line segment generated by first two points and also
                    direction = tripleCrossProd(Vector2.Subtract(simplex[1], simplex[0]), Vector2.Multiply(simplex[0], -1), Vector2.Subtract(simplex[1], simplex[0]));
                    break;

                case 3:

                    Vector2 side1 = Vector2.Subtract(simplex[1], simplex[2]);
                    Vector2 side2 = Vector2.Subtract(simplex[0], simplex[2]);
                    //vector orthogonal to the 2nd line segment generated (vertex 2 -> vertex 1)
                    Vector2 orthogonal1 = tripleCrossProd(side2, side1, side1);
                    //vector orthogonal to third line segment generated (vertex 3 -> vertex 1)
                    Vector2 orthogonal2 = tripleCrossProd(side1, side2, side2);
                    if (Vector2.Dot(orthogonal1, Vector2.Multiply(simplex[2], -1)) > 0)
                    {
                        direction = orthogonal1;
                        simplex.RemoveAt(0);
                    }
                    else if (Vector2.Dot(orthogonal2, Vector2.Multiply(simplex[2], -1)) > 0)
                    {
                        direction = orthogonal2;
                        simplex.RemoveAt(1);
                    }
                    else
                    {
                        return(true);
                    }
                    break;
                }
                Vector2 nextVert = Vector2.Subtract(poly1.supportFunction(direction), poly2.supportFunction(Vector2.Multiply(direction, -1)));
                if (Vector2.Dot(direction, nextVert) > 0)
                {
                    simplex.Add(nextVert);
                }
                else
                {
                    return(false);
                }
            }
        }
        public static Vector2 calculateIntersection(CollisionPoly poly1, CollisionPoly poly2, Vector2?velocity)
        {
            //Constructs basic simplex
            Vector2        direction = Vector2.Subtract(poly1.center(), poly2.center());
            List <Vector2> simplex   = new List <Vector2>();

            simplex.Add(Vector2.Subtract(poly1.supportFunction(direction), poly2.supportFunction(Vector2.Multiply(direction, -1))));
            direction = Vector2.Multiply(direction, -1);
            simplex.Add(Vector2.Subtract(poly1.supportFunction(direction), poly2.supportFunction(Vector2.Multiply(direction, -1))));
            direction = tripleCrossProd(Vector2.Subtract(simplex[1], simplex[0]), Vector2.Multiply(simplex[0], -1), Vector2.Subtract(simplex[1], simplex[0]));
            simplex.Add(Vector2.Subtract(poly1.supportFunction(direction), poly2.supportFunction(Vector2.Multiply(direction, -1))));

            //Calculates distance inside/outside object
            if (velocity.HasValue)
            {
                while (true)
                {
                    Edge    closestEdge = closestEdgeAlongVector(simplex, (Vector2)velocity);
                    Vector2 support     = Vector2.Subtract(poly1.supportFunction(closestEdge.normal), poly2.supportFunction(Vector2.Negate(closestEdge.normal)));
                    if (Math.Abs(Vector2.Dot(support, closestEdge.normal) - closestEdge.dist) <= 0.0001)
                    {
                        return(closestEdge.toOrigin);
                    }
                    else
                    {
                        simplex.Insert(closestEdge.index, support);
                    }
                }
            }
            else
            {
                while (true)
                {
                    Edge    closestEdge = closestEdgeToOrigin(simplex);
                    Vector2 support     = Vector2.Subtract(poly1.supportFunction(closestEdge.normal), poly2.supportFunction(Vector2.Negate(closestEdge.normal)));
                    if (Math.Abs(Vector2.Dot(support, closestEdge.normal) - closestEdge.dist) <= 0.00001)
                    {
                        return(Vector2.Multiply(closestEdge.normal, Vector2.Dot(support, closestEdge.normal)));
                    }
                    else
                    {
                        simplex.Insert(closestEdge.index, support);
                    }
                }
            }
        }