///Returns whether a line segment intersects a polygon (given a list of vertices)
        public static bool LineSegIntersectsPoly(LineSeg lns, List <Vector2> verts)
        {
            //Check to see if either end of the segment is in the polygon
            if (PointInPoly(lns.CenterA, verts) || PointInPoly(lns.CenterB, verts))
            {
                return(true);
            }

            int     j        = verts.Count - 1;
            LineSeg lnsCheck = new LineSeg();

            //checks every line segment in the polygon until an intersection is found
            for (int i = 0; i < verts.Count; i++)
            {
                lnsCheck.SetA(verts[i]);
                lnsCheck.SetB(verts[j]);
                if (LineSegIntersectsLineSeg(lns, lnsCheck))
                {
                    return(true);
                }

                j = i;
            }

            return(false);
        }
        ///Returns whether a line segment intersects a circle
        public static bool LineSegIntersectsCircle(LineSeg lns, Circle c)
        {
            //for efficiency, check if either end of the line is in the circle first
            if (PointInCircle(lns.CenterA, c) || PointInCircle(lns.CenterB, c))
            {
                return(true);
            }

            Vector2 point = Vector2.zero;

            //do checks to see whether the slope is 0 or infinite
            if (Mathf.Approximately(lns.Slope, 0f))
            {
                point = new Vector2(c.WorldCenter.x, lns.CenterA.y);
            }
            else if (lns.Slope == float.PositiveInfinity)
            {
                point = new Vector2(lns.CenterA.x, c.WorldCenter.y);
            }
            else
            {
                //get negative reciprocal of slope of line segment to find a new perpendicular line
                float slope = -1f / lns.Slope;
                //find the offset that the new line needs to also contain the center of the circle
                float offset = -slope * c.WorldCenter.x + c.WorldCenter.y;
                //calculate point of intersection between the perpendicular lines
                point.x = (lns.Offset - offset) / (slope - lns.Slope);
                point.y = slope * point.x + offset;
            }

            //check if the calculated point is on the line segment and in the circle
            return(PointInCircle(point, c) && PointOnLineSeg(point, lns));
        }
        /* Poly methods */

        #region

        ///Returns whether a polygon intersects another polygon (given a list of vertices)
        public static bool PolyIntersectsPoly(List <Vector2> verts1, List <Vector2> verts2)
        {
            //check to see if any vertices exist inside either polygon (more efficient and catches most cases)
            for (int i = 0; i < verts1.Count; i++)
            {
                Vector2 vert = verts1[i];

                if (PointInPoly(vert, verts2))
                {
                    return(true);
                }
            }

            for (int i = 0; i < verts2.Count; i++)
            {
                Vector2 vert = verts2[i];

                if (PointInPoly(vert, new List <Vector2>(verts1)))
                {
                    return(true);
                }
            }

            //check to see if any of the edges of a polygon intersect with the edges of the other
            //this code ensures concave shapes work too but it's potentially slow
            LineSeg lnsCheck = new LineSeg();
            int     j        = verts1.Count - 1;

            for (int i = 0; i < verts1.Count; i++)
            {
                lnsCheck.SetA(verts1[i]);
                lnsCheck.SetB(verts1[j]);
                if (LineSegIntersectsPoly(lnsCheck, verts2))
                {
                    return(true);
                }

                j = i;
            }

            return(false);
        }
        ///Returns whether a point lies on the perimeter of a polygon given its vertices
        public static bool PointOnPolyPerimeter(Vector2 p, List <Vector2> verts)
        {
            LineSeg lineCheck = new LineSeg();
            int     j         = verts.Count - 1;

            //checks every line segment of the polygon to see if the point lies on any segment
            for (int i = 0; i < verts.Count; i++)
            {
                lineCheck.SetA(verts[i]);
                lineCheck.SetB(verts[j]);
                if (PointOnLineSeg(p, lineCheck))
                {
                    return(true);
                }

                j = i;
            }

            return(false);
        }
        ///Returns whether a circle intersects a polygon (given a list of vertices)
        public static bool CircleIntersectsPoly(Circle c, List <Vector2> verts)
        {
            //check to see if the center of the circle is in the poly
            if (PointInPoly(c.WorldCenter, verts))
            {
                return(true);
            }

            //check to see if any points are in the circle
            for (int i = 0; i < verts.Count; i++)
            {
                Vector2 vert = verts[i];

                if (PointInCircle(vert, c))
                {
                    return(true);
                }
            }

            LineSeg lnsCheck = new LineSeg();
            int     j        = verts.Count - 1;

            //check each line segment of the polygon until an intersection is found
            for (int i = 0; i < verts.Count; i++)
            {
                lnsCheck.SetA(verts[i]);
                lnsCheck.SetB(verts[j]);
                if (LineSegIntersectsCircle(lnsCheck, c))
                {
                    return(true);
                }

                j = i;
            }

            return(false);
        }
        /* LineSeg methods */

        #region

        ///Returns whether a line segment intersects another line segment
        public static bool LineSegIntersectsLineSeg(LineSeg lns1, LineSeg lns2)
        {
            //if lines have the same slope (i.e. parallel or collinear)
            if (Mathf.Approximately(lns1.Slope, lns2.Slope))
            {
                //returns whether the ends of either segment lies on either segment
                return(PointOnLineSeg(lns1.CenterA, lns2) ||
                       PointOnLineSeg(lns1.CenterB, lns2) ||
                       PointOnLineSeg(lns2.CenterA, lns1) ||
                       PointOnLineSeg(lns2.CenterB, lns1));
            }

            Vector2 p;

            //check to see if either line 1 or 2 are vertical (slope would be infinite)
            //slope and offset are needed for slope intercept form calculation (y = mx + b)
            if (lns1.Slope == float.PositiveInfinity)
            {
                p.x = lns1.Offset;
                p.y = lns2.Slope * p.x + lns2.Offset;
            }
            else if (lns2.Slope == float.PositiveInfinity)
            {
                p.x = lns2.Offset;
                p.y = lns1.Slope * p.x + lns1.Offset;
            }
            else
            {
                //find point of intersection for line equations
                p.x = (lns2.Offset - lns1.Offset) / (lns1.Slope - lns2.Slope);
                p.y = lns1.Slope * p.x + lns1.Offset;
            }

            //return whether the calculated point is on both line segments
            return(PointOnLineSeg(p, lns1) && PointOnLineSeg(p, lns2));
        }
 ///Returns whether a line segment intersects a polygon
 public static bool LineSegIntersectsPoly(LineSeg lns, Poly p)
 {
     return(LineSegIntersectsPoly(lns, p.GetOffsetVerts()));
 }
 ///Returns whether a point lies on a line segment
 public static bool PointOnLineSeg(Vector2 p, LineSeg lns)
 {
     //if the distance between p and the segment ends is equal to the length of the segment, then point is on the segment
     return(Mathf.Approximately(Vector2.Distance(p, lns.CenterA) + Vector2.Distance(p, lns.CenterB), lns.Length));
 }