static public Slice2D ComplexCutSlice(Polygon2D polygon, ComplexCut complexCut)
        {
            List <Vector2D> slice  = complexCut.GetPointsList().ToVector2DList();
            Slice2D         result = Slice2D.Create(null, complexCut);

            if (slice.Count < 1)
            {
                return(result);
            }

            if (Math2D.SliceIntersectItself(slice))
            {
                Debug.LogWarning("Slicer2D: Complex Cut Slicer intersected with itself!");

                return(result);
            }

            Vector2D startPoint = null;

            foreach (Vector2D id in slice)
            {
                if (polygon.PointInPoly(id) == false)
                {
                    startPoint = id;
                    break;
                }
            }

            Polygon2D newPolygon = new Polygon2D(slice);

            slice = Vector2DList.GetListStartingPoint(slice, startPoint);
            slice.Add(startPoint);

            if (polygon.PolyInPoly(newPolygon))
            {
                polygon.AddHole(newPolygon);
                result.AddPolygon(polygon);
                return(result);
            }

            result = Slicer.Slice(polygon, slice);

            return(result);
        }
        static public Slice2D LinearCutSlice(Polygon2D polygon, LinearCut linearCut)
        {
            List <Vector2D> slice  = linearCut.GetPointsList().ToVector2DList();
            Slice2D         result = Slice2D.Create(null, linearCut);

            if (slice.Count < 1)
            {
                return(result);
            }

            Vector2D startPoint = null;

            foreach (Vector2D id in slice)
            {
                if (polygon.PointInPoly(id) == false)
                {
                    startPoint = id;
                    break;
                }
            }

            Polygon2D newPolygon = new Polygon2D(slice);

            slice = Vector2DList.GetListStartingPoint(slice, startPoint);
            slice.Add(startPoint);

            if (polygon.PolyInPoly(newPolygon))
            {
                polygon.AddHole(newPolygon);
                result.AddPolygon(polygon);
                return(result);
            }

            result = Slicer.Slice(polygon, slice);

            return(result);
        }
        // Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice
        static public Slice2D PolygonSlice(Polygon2D polygon, Polygon2D slicePolygon)
        {
            List <Polygon2D> holes = polygon.holesList;

            polygon           = new Polygon2D(new List <Vector2D>(polygon.pointsList));
            polygon.holesList = holes;

            slicePolygon = new Polygon2D(new List <Vector2D>(slicePolygon.pointsList));

            Slice2D result = Slice2D.Create(null, polygon);

            Sliceable2D.SliceType tempSliceType = Sliceable2D.complexSliceType;
            Sliceable2D.complexSliceType = Sliceable2D.SliceType.SliceHole;

            slicePolygon.Normalize();
            polygon.Normalize();

            // Eat a polygon completely
            // Complex Slicer does not register slice in this case
            if (slicePolygon.PolyInPoly(polygon) == true)
            {
                result.AddPolygon(polygon);
                return(result);
            }

            // Cut a hole inside (how does this work if it collides with other hole?)
            if (polygon.PolyInPoly(slicePolygon) == true)
            {
                polygon.AddHole(slicePolygon);
                result.AddPolygon(polygon);

                Math2D.Distance distance = Math2D.Distance.PolygonToPolygon(polygon, slicePolygon);
                if (distance != null && distance.value < precision)
                {
                    return(SlicePolygonFromEdge(polygon, slicePolygon));
                }

                return(result);
            }

            // Act as Regular Slice
            Vector2D startPoint = GetDoubleStartingPoint(polygon, slicePolygon);

            if (startPoint == null)
            {
                startPoint = GetSingleStartingPoint(polygon, slicePolygon);
            }
            else
            {
                /*
                 * int count = slicePolygon.pointsList.Count;
                 * int id = slicePolygon.pointsList.IndexOf(startPoint);
                 * Debug.Log("[1] " + slicePolygon.pointsList[id].ToString() + " " + slicePolygon.pointsList[(id + 1) % count].ToString() + " " + slicePolygon.pointsList[(id + 2) % count].ToString());
                 *
                 *
                 * Vector2D o = slicePolygon.pointsList[id + 1];
                 *
                 * Vector2D p = (startPoint + o) / 2;
                 * slicePolygon.pointsList.Insert(id , p);
                 *
                 * startPoint = p;
                 *
                 * Debug.Log(startPoint.ToString() + " " +  o.ToString() + " " + p.ToString());
                 *
                 * Debug.Log("[2] " + slicePolygon.pointsList[id].ToString() + " " + slicePolygon.pointsList[(id + 1) % count].ToString() + " " + slicePolygon.pointsList[(id + 2) % count].ToString());
                 */
            }



            if (startPoint == null)
            {
                if (Math2D.PolyIntersectPoly(polygon, slicePolygon))
                {
                    return(SlicePolygonFromEdge(polygon, slicePolygon));
                }

                Debug.LogWarning("Starting Point Error In PolygonSlice");
                return(result);
            }

            slicePolygon.pointsList = Vector2DList.GetListStartingPoint(slicePolygon.pointsList, startPoint);

            /*
             * List<Vector2D> s = new List<Vector2D> ();
             * foreach (Pair2D pair in Pair2D.GetList(polygonSlice.pointsList, false)) {
             *      List<Vector2D> stackList = polygon.GetListSliceIntersectPoly(pair);
             *      stackList = Vector2DList.GetListSortedToPoint (stackList, pair.A);
             *      Vector2D old = pair.A;
             *      s.Add (old);
             *
             *      foreach (Vector2D id in stackList) {
             *              s.Add (new Vector2D((old.GetX() + id.GetX()) / 2, (old.GetY() + id.GetY()) / 2));
             *              old = id;
             *      }
             * }
             *
             * polygonSlice.pointsList = s;
             */

            slicePolygon.AddPoint(startPoint);

            // Not Necessary
            if (polygon.SliceIntersectPoly(slicePolygon.pointsList) == false)
            {
                return(result);
            }

            // Slice More Times?
            result = Slicer.Slice(polygon, new List <Vector2D> (slicePolygon.pointsList));

            if (result.GetPolygons().Count < 1)
            {
                Debug.LogWarning("Slicer2D: Returns Empty Polygon Slice");
            }

            Sliceable2D.complexSliceType = tempSliceType;

            return(result);
        }