Пример #1
0
        static private Merge2D SliceWithoutHoles(Polygon2D polygon, List <Vector2D> slice, MergeCollision mergeCollision)
        {
            Merge2D result = Merge2D.Create(slice);

            // Simple non-hole slice
            Polygon2D polyA = new Polygon2D();
            Polygon2D polyB = new Polygon2D();

            Polygon2D currentPoly = polyA;

            List <Vector2D> slices = new List <Vector2D>(mergeCollision.GetPoints());


            foreach (Pair2D p in Pair2D.GetList(polygon.pointsList))
            {
                List <Vector2D> intersections = Math2D.GetListLineIntersectSlice(p, slice);

                if (intersections.Count() > 0)
                {
                    if (intersections.Count == 2)
                    {
                        Vector2D first = intersections.First();
                        Vector2D last  = intersections.Last();

                        if (Vector2D.Distance(last, p.A) < Vector2D.Distance(first, p.A))
                        {
                            first = intersections.Last();
                            last  = intersections.First();
                        }

                        // Add Inside Points
                        if (mergeCollision.GetPoints().Count > 0)                           // InsidePlus
                        {
                            if (Vector2D.Distance(first, mergeCollision.Last()) < Vector2D.Distance(first, mergeCollision.First()))
                            {
                                mergeCollision.Reverse();
                            }

                            currentPoly.AddPoints(mergeCollision.GetPoints());                              // InsidePlus
                        }
                        /////

                        currentPoly = polyB;

                        if (mergeCollision.GetPoints().Count > 0)                           // InsidePlus(
                        {
                            currentPoly.AddPoints(mergeCollision.GetPoints());              // InsidePlus
                        }

                        currentPoly = polyA;
                    }

                    if (intersections.Count == 1)
                    {
                        Vector2D intersection = intersections.First();

                        ///// Add Inside Points
                        if (mergeCollision.GetPoints().Count > 0)                           //InsidePlus
                        {
                            if (Vector2D.Distance(intersection, mergeCollision.Last()) < Vector2D.Distance(intersection, mergeCollision.First()))
                            {
                                mergeCollision.Reverse();
                            }

                            currentPoly.AddPoints(mergeCollision.GetPoints());                              // InsidePlus
                        }
                        /////

                        currentPoly = (currentPoly == polyA) ? polyB : polyA;
                    }
                }

                currentPoly.AddPoint(p.B);
            }

            Polygon2D mainPoly = polyA;

            if (polyB != null && polyB.GetArea() > polyA.GetArea())
            {
                mainPoly = polyB;
            }

            result.AddPolygon(mainPoly);

            foreach (Polygon2D hole in polygon.holesList)
            {
                mainPoly.AddHole(hole);
            }

            result.AddSlice(slices);

            return(result);
        }
Пример #2
0
        // Complex Merge
        static public Merge2D Merge(Polygon2D polygon, List <Vector2D> slice)
        {
            Merge2D result = Merge2D.Create(slice);

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

            // Normalize into clockwise
            polygon.Normalize();

            Rect sliceRect   = Math2D.GetBounds(slice);
            Rect polygonRect = polygon.GetBounds();

            if (sliceRect.Overlaps(polygonRect) == false)
            {
                return(result);
            }

            List <List <Vector2D> > slices = GetSplitSlices(polygon, slice);

            // Adjusting split lines before performing convex split

            result.AddPolygon(polygon);

            foreach (List <Vector2D> id in slices)
            {
                if (id.Count < 1)
                {
                    continue;
                }

                foreach (Vector2D p in id)
                {
                    result.AddCollision(p);
                }

                // Sclice line points generated from intersections list
                Vector2D vec0 = id.First();
                vec0.Push(Vector2D.Atan2(vec0, id[1]), precision);                      // ERROR

                Vector2D vec1 = id.Last();
                vec1.Push(Vector2D.Atan2(vec1, id[id.Count - 2]), precision);

                // For each in polygons list attempt convex split
                List <Polygon2D> temp = new List <Polygon2D>(result.polygons);               // necessary?
                foreach (Polygon2D poly in temp)
                {
                    Merge2D resultList = SingleMerge(poly, id);

                    if (resultList.slices.Count > 0)
                    {
                        foreach (List <Vector2D> i in resultList.slices)
                        {
                            result.AddSlice(i);
                        }
                    }

                    if (resultList.polygons.Count > 0)
                    {
                        foreach (Polygon2D i in resultList.polygons)
                        {
                            result.AddPolygon(i);
                        }

                        // If it's possible to perform convex split, remove parent polygon from result list
                        result.polygons.Remove(poly);
                    }
                }
            }

            return(result);
        }