public static bool Intersect(Circle c, Box b, out SIntersectionInfo collInfo)
        {
            collInfo = new SIntersectionInfo();

            //Special case: Our center is inside the box, this is the easiest case to detect, hardest to handle
            if (PointInBox(b, c.Center))
            {
                //CHEAT: project our center's circle onto every edge
                //       pick the closest one
                //       say that we interesected there (not accurate, can create bugs for fast moving objects or small circles)

                //Each edge of the box
                Edge[] edges =
                {
                    new Edge(b.tlCorner, b.trCorner),
                    new Edge(b.trCorner, b.brCorner),
                    new Edge(b.brCorner, b.blCorner),
                    new Edge(b.blCorner, b.tlCorner)
                };

                float smallestDistance = float.MaxValue;
                foreach (Edge e in edges)
                {
                    Vector2 proj = (Vector2.Dot(c.Center - e.P1, e.Dir) / Vector2.Dot(e.Dir, e.Dir)) * e.Dir;
                    float   dist = ((c.Center - e.P1) - proj).magnitude;
                    //Each time we find an edge closer to our center, set ourselves to intersect there
                    if (dist < smallestDistance)
                    {
                        smallestDistance            = dist;
                        collInfo.intersectionPoint  = proj + e.P1;
                        collInfo.intersectionDepth  = (c.Center - collInfo.intersectionPoint).magnitude;
                        collInfo.intersectionNormal = new Vector2(-e.Dir.y, e.Dir.x).normalized;
                    }
                }
                return(true);
            }
            //Otherwise there may be an intersection despite our center not being inside
            else
            {
                return(LineIntersectCircle(c, new Edge(b.tlCorner, b.trCorner), out collInfo) ||
                       LineIntersectCircle(c, new Edge(b.trCorner, b.brCorner), out collInfo) ||
                       LineIntersectCircle(c, new Edge(b.brCorner, b.blCorner), out collInfo) ||
                       LineIntersectCircle(c, new Edge(b.blCorner, b.tlCorner), out collInfo));
            }
        }
        public static bool LineIntersectCircle(Circle c, Edge e, out SIntersectionInfo collInfo)
        {
            float ratioProj = (Vector2.Dot(c.Center - e.P1, e.Dir) / Vector2.Dot(e.Dir, e.Dir));

            collInfo = new SIntersectionInfo();
            //Verify if our projected point lies on the actual edge, aka whether it maps to a length between 0 and 1 of the edge
            if (ratioProj >= 0.0f && ratioProj <= 1.0f)
            {
                //Get the perpendicular of the projection triangle formed by the center and the edge starting at P1
                Vector2 perp = (c.Center - e.P1) - (ratioProj * e.Dir);
                //Then return whether the distance between the center and the edge is smaller than the radius
                if (perp.magnitude <= c.Radius)
                {
                    //Set the collision depth and the collision point to be where the edge of the circle is past the edge
                    collInfo.intersectionDepth  = c.Radius - perp.magnitude;
                    collInfo.intersectionPoint  = c.Center - perp;
                    collInfo.intersectionNormal = new Vector2(-e.Dir.y, e.Dir.x).normalized;
                    return(true);
                }
            }
            else
            {
                //If our projection isn't between the two points, check whether the edge points are within the radius of the center
                //The collision will occur at the edge points if there is one
                if ((c.Center - e.P1).magnitude <= c.Radius)
                {
                    collInfo.intersectionDepth  = c.Radius - (c.Center - e.P1).magnitude;
                    collInfo.intersectionPoint  = e.P1;
                    collInfo.intersectionNormal = new Vector2(-e.Dir.y, e.Dir.x).normalized;
                    return(true);
                }
                else if ((c.Center - e.P2).magnitude <= c.Radius)
                {
                    collInfo.intersectionDepth  = c.Radius - (c.Center - e.P2).magnitude;
                    collInfo.intersectionPoint  = e.P2;
                    collInfo.intersectionNormal = new Vector2(-e.Dir.y, e.Dir.x).normalized;
                    return(true);
                }
            }

            return(false);
        }
        //Test whether circle 1 intersects circle 2
        public static bool Intersect(Circle c1, Circle c2, out SIntersectionInfo collision)
        {
            float distanceCenter = (c1.Center - c2.Center).magnitude;

            collision = new SIntersectionInfo();

            //Calculate whether the distance between centers is smaller than radius sum (consider edges touching a collision)
            if (distanceCenter <= c1.Radius + c2.Radius)
            {
                collision.intersectionDepth = c1.Radius + c2.Radius - distanceCenter;
                //Set the intersection point on the edge of the second circle towards the first circle center
                collision.intersectionPoint  = c2.Center + (c1.Center - c2.Center).normalized * c2.Radius;
                collision.intersectionNormal = (c1.Center - c2.Center).normalized;
                return(true);
            }
            else
            {
                return(false);
            }
        }