public bool DoesSegmentCrossContour(Vector2 segmentStart, Vector2 segmentEnd, ReadOnlyCollection <Vector2> contour)
        {
            if (contour == null)
            {
                throw new ArgumentNullException("contour");
            }
            else if (contour.Count < 2)
            {
                throw new ArgumentException("contour has less than two points, and is therefore invalid");
            }

            for (int i = 0; i < contour.Count - 1; i++)
            {
                Vector2 dummy;

                if (Geometry2D.AreLineSegmentsCrossing(segmentStart, segmentEnd, out dummy, contour[i], contour[i + 1], out dummy))
                {
                    return(true);
                }
            }

            return(false);
        }
        /*
         * There are a handful of possible cases for this method.
         *
         * In the first case, CenterLeftContour and CenterRightContour intersect each-other.
         * In that case, we want to remove all of the points in each contour beyond the other
         * and then join them at the intersect. We do this by checking the contours in opposite
         * directions. Because all contours are oriented clockwise around their cell, if we
         * check for line segment collision carefully we'll know exactly which points need to
         * be removed. Any intersection will appear close to the beginning of CenterRightContour
         * and the end of CenterLeftContour. Thus we work up CenterRightContour and down
         * CenterLeftContour. Once we find an intersection, we strip points from the beginning of
         * CenterRightContour and the end of CenterLeftContour and add the intersection point at
         * the beginning and end, respectively.
         *
         * In the second case, CenterLeftContour doesn't touch CenterRightContour but CenterRightContour
         * extends undesirably into the rivers. To handle this, we extrapolate forward from
         * CenterLeftContour using its last and second to last points, check for an intersection,
         * and then cull points and add the intersection as above.
         *
         * In the third case, CenterRightContour doesn't touch CenterLeftContour but CenterLeftContour
         * extends undesirably into the rivers. We handle this much the same way, extrapolating
         * backwards from the first and second points of CenterRightContour, checking for an intersecton,
         * and culling as needed.
         *
         * In the fourth case, neither contours touch each-other or extend into the rivers. In that case,
         * we extrapolate on both contours (forward for CenterLeft, backward for CenterRight) and add
         * their intersection without culling.
         */
        public void RationalizeCellContours(
            IHexCell center, HexDirection direction
            )
        {
            List <Vector2> centerLeftContour  = CellEdgeContourCanon.GetContourForCellEdge(center, direction.Previous()).ToList();
            List <Vector2> centerRightContour = CellEdgeContourCanon.GetContourForCellEdge(center, direction).ToList();

            int lastOutsideLeftIndex  = centerLeftContour.Count - 1;
            int lastOutsideRightIndex = 0;

            Vector2 contourIntersect = Vector2.zero;

            bool hasFoundIntersect = false;

            //We multiply our extrapolating vector by some relatively large number to make it more likely
            //that they intersect properly.
            for (; lastOutsideLeftIndex > 0; lastOutsideLeftIndex--)
            {
                if (Geometry2D.AreLineSegmentsCrossing(
                        centerLeftContour[lastOutsideLeftIndex], centerLeftContour [lastOutsideLeftIndex - 1], out contourIntersect,
                        centerRightContour[0], centerRightContour[0] + (centerRightContour[0] - centerRightContour[1]) * 10, out contourIntersect
                        ))
                {
                    hasFoundIntersect = true;
                    break;
                }

                for (lastOutsideRightIndex = 0; lastOutsideRightIndex < centerRightContour.Count - 1; lastOutsideRightIndex++)
                {
                    if (Geometry2D.AreLineSegmentsCrossing(
                            centerLeftContour [lastOutsideLeftIndex], centerLeftContour [lastOutsideLeftIndex - 1], out contourIntersect,
                            centerRightContour[lastOutsideRightIndex], centerRightContour[lastOutsideRightIndex + 1], out contourIntersect
                            ))
                    {
                        hasFoundIntersect = true;
                        break;
                    }
                }

                if (hasFoundIntersect)
                {
                    break;
                }
            }

            if (!hasFoundIntersect)
            {
                Vector2 lastLeft       = centerLeftContour.Last();
                Vector2 secondLastLeft = centerLeftContour[centerLeftContour.Count - 2];

                if (Geometry2D.AreLineSegmentsCrossing(
                        lastLeft, lastLeft + (lastLeft - secondLastLeft) * 10, out contourIntersect,
                        centerRightContour[0], centerRightContour[0] + (centerRightContour[0] - centerRightContour[1]) * 10, out contourIntersect
                        ))
                {
                    hasFoundIntersect = true;
                }

                for (lastOutsideRightIndex = 0; lastOutsideRightIndex < centerRightContour.Count - 1; lastOutsideRightIndex++)
                {
                    if (Geometry2D.AreLineSegmentsCrossing(
                            lastLeft, lastLeft + (lastLeft - secondLastLeft) * 10, out contourIntersect,
                            centerRightContour[lastOutsideRightIndex], centerRightContour[lastOutsideRightIndex + 1], out contourIntersect
                            ))
                    {
                        hasFoundIntersect = true;
                        break;
                    }
                }
            }

            if (lastOutsideLeftIndex > 0)
            {
                centerLeftContour.RemoveRange(lastOutsideLeftIndex, centerLeftContour.Count - lastOutsideLeftIndex);
            }

            if (lastOutsideRightIndex < centerRightContour.Count - 1)
            {
                centerRightContour.RemoveRange(0, lastOutsideRightIndex + 1);
            }

            if (hasFoundIntersect)
            {
                centerLeftContour.Add(contourIntersect);

                centerRightContour.Insert(0, contourIntersect);
            }

            CellEdgeContourCanon.SetContourForCellEdge(center, direction.Previous(), centerLeftContour);
            CellEdgeContourCanon.SetContourForCellEdge(center, direction, centerRightContour);
        }