Пример #1
0
        static public Slice2D ExplodeByPoint(Polygon2D polygon, Vector2D point, int explosionSlices = 0)
        {
            if (explosionSlices < 1)
            {
                explosionSlices = Slicer2DSettings.GetExplosionSlices();
            }

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

            if (polygon.PointInPoly(point) == false)
            {
                return(result);
            }

            float sliceRot = UnityEngine.Random.Range(0, 360);

            Polygon2D hole = Polygon2D.Create(Polygon2D.PolygonType.Rectangle, 0.1f);

            hole = hole.ToOffset(point);
            polygon.AddHole(hole);

            result.AddPolygon(polygon);

            int tries = 0;

            while (result.GetPolygons().Count < explosionSlices)
            {
                foreach (Polygon2D p in new List <Polygon2D>(result.GetPolygons()))
                {
                    sliceRot += UnityEngine.Random.Range(15, 45) * Mathf.Deg2Rad;

                    Vector2D v = new Vector2D(point);
                    v.Push(sliceRot, 0.4f);

                    Slice2D newResult = SliceFromPoint(p, v, sliceRot);

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

                        foreach (Polygon2D poly in newResult.GetPolygons())
                        {
                            result.AddPolygon(poly);
                        }
                        result.RemovePolygon(p);
                    }
                }

                tries += 1;
                if (tries > 20)
                {
                    return(result);
                }
            }

            return(result);
        }
Пример #2
0
        // Slice From Point
        static public Slice2D SliceFromPoint(Polygon2D polygon, Vector2D point, float rotation)
        {
            Slice2D result = Slice2D.Create(null, point, rotation);

            // Normalize into clockwise
            polygon.Normalize();

            Vector2D sliceA = new Vector2D(point);
            Vector2D sliceB = new Vector2D(point);

            sliceA.Push(rotation, 1e+10f / 2);
            sliceB.Push(rotation, -1e+10f / 2);

            if (polygon.PointInPoly(point) == false)
            {
                return(result);
            }

            // Getting the list of intersections
            List <Vector2D> intersectionsA = polygon.GetListLineIntersectPoly(new Pair2D(point, sliceA));
            List <Vector2D> intersectionsB = polygon.GetListLineIntersectPoly(new Pair2D(point, sliceB));

            // Sorting intersections from one point
            if (intersectionsA.Count > 0 && intersectionsB.Count > 0)
            {
                sliceA = Vector2DList.GetListSortedToPoint(intersectionsA, point) [0];
                sliceB = Vector2DList.GetListSortedToPoint(intersectionsB, point) [0];
            }
            else
            {
                return(result);
            }

            List <Pair2D> collisionList = new List <Pair2D>();

            collisionList.Add(new Pair2D(sliceA, sliceB));

            result.AddPolygon(polygon);

            foreach (Pair2D id in collisionList)
            {
                result.AddCollision(id.A);
                result.AddCollision(id.B);

                // Sclice line points generated from intersections list
                Vector2D vec0 = new Vector2D(id.A);
                Vector2D vec1 = new Vector2D(id.B);

                double rot = Vector2D.Atan2(vec0, vec1);

                // Slightly pushing slice line so it intersect in all cases
                vec0.Push(rot, LinearSlicer.precision);
                vec1.Push(rot, -LinearSlicer.precision);

                // For each in polygons list attempt convex split
                List <Polygon2D> temp = new List <Polygon2D>(result.GetPolygons());               // necessary?
                foreach (Polygon2D poly in temp)
                {
                    // NO, that's the problem
                    Slice2D resultList = LinearSlicer.Slice(poly, new Pair2D(vec0, vec1));

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

                        foreach (Polygon2D i in resultList.GetPolygons())
                        {
                            result.AddPolygon(i);
                        }

                        // If it's possible to perform splice, remove parent polygon from result list
                        result.RemovePolygon(poly);
                    }
                }
            }
            result.RemovePolygon(polygon);
            return(result);
        }
Пример #3
0
            static public Slice2D Slice(Polygon2D polygon, Pair2D slice, Polygon2D holeA, Polygon2D holeB)
            {
                Slice2D result = Slice2D.Create(null, slice);

                if (holeA == holeB)
                {
                    Polygon2D polyA = new Polygon2D(polygon.pointsList);
                    Polygon2D polyB = new Polygon2D();
                    Polygon2D polyC = new Polygon2D();

                    Polygon2D currentPoly = polyB;

                    foreach (Pair2D pair in Pair2D.GetList(holeA.pointsList))
                    {
                        Vector2D point = Math2D.GetPointLineIntersectLine(slice, pair);
                        if (point != null)
                        {
                            polyB.AddPoint(point);
                            polyC.AddPoint(point);
                            currentPoly = (currentPoly == polyB) ? polyC : polyB;
                        }
                        currentPoly.AddPoint(pair.B);
                    }

                    if (polyB.pointsList.Count > 2 && polyC.pointsList.Count > 2)
                    {
                        if (polyB.GetArea() > polyC.GetArea())
                        {
                            polyA.AddHole(polyB);
                            result.AddPolygon(polyC);
                        }
                        else
                        {
                            result.AddPolygon(polyB);
                            polyA.AddHole(polyC);
                        }

                        result.AddPolygon(polyA);
                    }

                    return(result);
                    // Cross From Side To Polygon
                }
                else if (polygon.PointInPoly(slice.A) == false || polygon.PointInPoly(slice.B) == false)
                {
                    Polygon2D holePoly = (holeA != null) ? holeA : holeB;

                    if (holePoly != null)
                    {
                        Polygon2D polyA = new Polygon2D();
                        Polygon2D polyB = new Polygon2D(holePoly.pointsList);

                        polyB.pointsList.Reverse();

                        polyA.AddPoints(Vector2DList.GetListStartingIntersectLine(polygon.pointsList, slice));
                        polyA.AddPoints(Vector2DList.GetListStartingIntersectLine(polyB.pointsList, slice));

                        foreach (Polygon2D poly in polygon.holesList)
                        {
                            if (poly != holePoly)
                            {
                                polyA.AddHole(poly);
                            }
                        }

                        result.AddPolygon(polyA);
                        return(result);
                    }
                }
                return(result);
            }
Пример #4
0
            static public Slice2D Slice(Polygon2D polygon, Pair2D slice)
            {
                Slice2D result = Slice2D.Create(null, slice);

                if (polygon.LineIntersectHoles(slice).Count > 0)
                {
                    // When does this happen? - Only when using point slicer!!!
                    if (Slicer2D.Debug.enabled)
                    {
                        Debug.LogWarning("Slicer2D: Slice Intersect Holes (Point Slicer?)");
                    }
                    return(result);
                }

                Polygon2D polyA = new Polygon2D();
                Polygon2D polyB = new Polygon2D();

                Polygon2D currentPoly = polyA;

                int collisionCount = 0;

                Pair2D id = Pair2D.Zero();

                id.A = polygon.pointsList.Last();

                for (int i = 0; i < polygon.pointsList.Count; i++)
                {
                    id.B = polygon.pointsList[i];

                    Vector2D intersection = Math2D.GetPointLineIntersectLine(id, slice);

                    if (intersection != null)
                    {
                        polyA.AddPoint(intersection);
                        polyB.AddPoint(intersection);

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

                        collisionCount++;
                    }

                    currentPoly.AddPoint(id.B);

                    id.A = id.B;
                }

                switch (collisionCount)
                {
                case 2:
                    if (polyA.pointsList.Count() >= 3)
                    {
                        result.AddPolygon(polyA);
                    }

                    if (polyB.pointsList.Count() >= 3)
                    {
                        result.AddPolygon(polyB);
                    }

                    foreach (Polygon2D poly in result.GetPolygons())
                    {
                        foreach (Polygon2D hole in polygon.holesList)
                        {
                            if (poly.PolyInPoly(hole) == true)
                            {
                                poly.AddHole(hole);
                            }
                        }
                    }

                    return(result);

                default:

                    if (Slicer2D.Debug.enabled)
                    {
                        //Debug.LogWarning("Slicer2D: Linear Slice with " + collisionCount + " collision points");
                    }
                    break;
                }

                return(result);
            }
Пример #5
0
        static private Slice2D MultipleSlice(Polygon2D polygon, Pair2D slice)
        {
            Slice2D result = Slice2D.Create(null, slice);

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

            //Debug.Log(slices.Count);

            //Debug.Log(slices[0].A.ToVector2() + " " + slices[0].B.ToVector2());
            //Debug.Log(slices[1].A.ToVector2() + " " + slices[1].B.ToVector2());

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

            result.AddPolygon(polygon);

            // Slice line points generated from intersections list
            foreach (Pair2D id in slices)
            {
                result.AddCollision(id.A);
                result.AddCollision(id.B);

                Vector2D vec0 = new Vector2D(id.A);
                Vector2D vec1 = new Vector2D(id.B);

                double rot = Vector2D.Atan2(vec0, vec1);

                // Slightly pushing slice line so it intersect in all cases
                vec0.Push(rot, precision);
                vec1.Push(rot, -precision);

                Pair2D line = new Pair2D(vec0, vec1);

                // For each in polygons list attempt convex split
                foreach (Polygon2D poly in (new List <Polygon2D>(result.GetPolygons())))
                {
                    Slice2D resultList = SingleSlice(poly, line);

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

                        result.AddSlice(line);

                        foreach (Polygon2D i in resultList.GetPolygons())
                        {
                            result.AddPolygon(i);
                        }

                        // If it's possible to perform splice, remove currently sliced polygon from result list
                        result.RemovePolygon(poly);
                    }
                }
            }

            result.RemovePolygon(polygon);
            return(result);
        }
Пример #6
0
            static public Slice2D Slice(Polygon2D polygon, Pair2D slice, Vector2D vertex)
            {
                Slice2D result = Slice2D.Create(null, slice);

                polygon.pointsList = Vector2DList.GetListStartingPoint(polygon.pointsList, vertex);

                Polygon2D polyA = new Polygon2D();
                Polygon2D polyB = new Polygon2D();

                Polygon2D currentPoly = polyA;

                int collisionCount = 0;

                Pair2D id = Pair2D.Zero();

                id.A = polygon.pointsList.Last();

                for (int i = 0; i < polygon.pointsList.Count; i++)
                {
                    id.B = polygon.pointsList[i];

                    Vector2D intersection = Math2D.GetPointLineIntersectLine(id, slice);

                    if (intersection != null)                       // && Vector2D.Distance(intersection, vertex) < 0.001f

                    {
                        if (polyA.pointsList.Count < 1 || Vector2D.Distance(intersection, polyA.pointsList.Last()) > 0.001f)
                        {
                            polyA.AddPoint(intersection);
                        }

                        if (polyB.pointsList.Count < 1 || Vector2D.Distance(intersection, polyB.pointsList.Last()) > 0.001f)
                        {
                            polyB.AddPoint(intersection);
                        }

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

                        collisionCount++;
                    }

                    if (currentPoly.pointsList.Count < 1 || Vector2D.Distance(id.B, currentPoly.pointsList.Last()) > 0.001f)
                    {
                        currentPoly.AddPoint(id.B);
                    }

                    id.A = id.B;
                }

                switch (collisionCount)
                {
                case 1:
                case 2:
                case 3:
                    if (polyA.pointsList.Count() >= 3)
                    {
                        result.AddPolygon(polyA);
                    }

                    if (polyB.pointsList.Count() >= 3)
                    {
                        result.AddPolygon(polyB);
                    }

                    foreach (Polygon2D poly in result.GetPolygons())
                    {
                        foreach (Polygon2D hole in polygon.holesList)
                        {
                            if (poly.PolyInPoly(hole) == true)
                            {
                                poly.AddHole(hole);
                            }
                        }
                    }

                    return(result);

                default:

                    if (Slicer2D.Debug.enabled)
                    {
                        Debug.LogWarning("Slicer2D: Vertex Linear Slice with " + collisionCount + " collision points " + slice.ToString());
                    }
                    break;
                }

                return(result);
            }