Exemplo n.º 1
0
    static private Slice2D SliceWithTwoHoles(Polygon polygon, Pair2f slice, Polygon holeA, Polygon holeB)
    {
        Slice2D result = Slice2D.Create();

        if (holeA == holeB)
        {
            Debug.LogError("Slicer2D: Incorrect Split 2: Cannot Split Into Same Hole");
            return(result);
        }

        Polygon polyA = new Polygon();
        Polygon polyB = new Polygon(polygon.pointsList);

        polyA.AddPoints(VectorList2f.GetListStartingIntersectLine(holeA.pointsList, slice));
        polyA.AddPoints(VectorList2f.GetListStartingIntersectLine(holeB.pointsList, slice));

        foreach (Polygon poly in polygon.holesList)
        {
            if (poly != holeA && poly != holeB)
            {
                polyB.AddHole(poly);
            }
        }

        polyB.AddHole(polyA);

        result.AddPolygon(polyB);
        return(result);
    }
Exemplo n.º 2
0
    static private Slice2D SliceWithTwoHoles(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice)
    {
        Slice2D result = Slice2D.Create();

        Polygon polyA = new Polygon();
        Polygon polyB = new Polygon(polygon.pointsList);

        Polygon holeA = polygon.PointInHole(slice.First());
        Polygon holeB = polygon.PointInHole(slice.Last());

        if (holeA == null || holeB == null)
        {
            Debug.LogError("Slicer2D: ERROR Split");              // Shouldn't really happen
            return(result);
        }

        List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(holeA.pointsList, slice);
        List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(holeB.pointsList, slice);

        polyA.AddPoints(pointsA);

        if (collisionSlice.Count > 0)
        {
            if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First()))
            {
                collisionSlice.Reverse();
            }

            polyA.AddPoints(collisionSlice);
        }

        polyA.AddPoints(pointsB);

        if (collisionSlice.Count > 0)
        {
            collisionSlice.Reverse();

            polyA.AddPoints(collisionSlice);
        }

        foreach (Polygon poly in polygon.holesList)
        {
            if (poly != holeA && poly != holeB)
            {
                polyB.AddHole(poly);
            }
        }

        polyB.AddHole(polyA);
        result.AddPolygon(polyB);

        return(result);
    }
Exemplo n.º 3
0
    // Linear Slice
    static public Slice2D Slice(Polygon polygon, Pair2f slice)
    {
        Slice2D result = Slice2D.Create();

        // Normalize into clockwise
        polygon.Normalize();

        // Getting the list of intersections
        List <Vector2f> intersections = polygon.GetListSliceIntersectPoly(slice);

        // Sorting intersections from one point
        intersections = VectorList2f.GetListSortedToPoint(intersections, slice.A);

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

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

        // Dividing intersections into single slices - This method doesn't look like very reliable!!!
        // Optimize this (polygon.PointInPoly) line // Fix this nonsense!!!
        foreach (Pair2f p in Pair2f.GetList(intersections, false))
        {
            if (polygon.PointInPoly(new Vector2f((p.B.GetX() + p.A.GetX()) / 2, (p.B.GetY() + p.A.GetY()) / 2)) == true)
            {
                collisionList.Add(p);
                intersections.Remove(p.A);
                intersections.Remove(p.B);
            }
        }

        result.AddPolygon(polygon);

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

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

            float rot = Vector2f.Atan2(vec0, vec1);

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

            // For each in polygons list attempt convex split
            foreach (Polygon poly in (new List <Polygon>(result.polygons)))
            {
                Slice2D resultList = SingleSlice(poly, new Pair2f(vec0, vec1));

                if (resultList.polygons.Count > 0)
                {
                    foreach (Polygon i in resultList.polygons)
                    {
                        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);
    }
Exemplo n.º 4
0
    static private Slice2D SliceWithOneHole(Polygon polygon, Pair2f slice, Polygon holeA, Polygon holeB)
    {
        Slice2D result = Slice2D.Create();

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

            Polygon currentPoly = polyB;

            foreach (Pair2f pair in Pair2f.GetList(holeA.pointsList))
            {
                Vector2f point = MathHelper.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)
        {
            Polygon holePoly = (holeA != null) ? holeA : holeB;

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

                polyB.pointsList.Reverse();

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

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

                result.AddPolygon(polyA);
                return(result);
            }
        }
        return(result);
    }
Exemplo n.º 5
0
    // Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice
    static public Slice2D Slice(Polygon polygon, Polygon polygonSlice)
    {
        Slice2D result = Slice2D.Create();

        Slicer2D.SliceType tempSliceType = Slicer2D.complexSliceType;
        Slicer2D.complexSliceType = Slicer2D.SliceType.SliceHole;

        polygonSlice.Normalize();
        polygon.Normalize();

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

        if (polygon.PolyInPoly(polygonSlice) == true)
        {
            polygon.AddHole(polygonSlice);
            result.AddPolygon(polygon);
            return(result);
        }

        // Act as Regular Slice
        Vector2f startPoint = null;

        foreach (Vector2f id in polygonSlice.pointsList)
        {
            if (polygon.PointInPoly(id) == false)
            {
                startPoint = id;
                break;
            }
        }


        if (startPoint == null)
        {
            Debug.LogError("Slicer2D: Starting Point Error In PolygonSlice");
            return(result);
        }

        polygonSlice.pointsList = VectorList2f.GetListStartingPoint(polygonSlice.pointsList, startPoint);
        polygonSlice.AddPoint(startPoint);

        //List<Vector2f> s = new List<Vector2f> ();
        //foreach (Pair2f pair in Pair2f.GetList(polygonSlice.pointsList, false)) {
        //	List<Vector2f> stackList = polygon.GetListSliceIntersectPoly(pair);
        //	stackList = VectorList2f.GetListSortedToPoint (stackList, pair.A);
        //	s.Add (pair.A);

        //foreach (Vector2f id in stackList)
        //	s.Add (id);
        //}

        //polygonSlice.pointsList = s;

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

        result = ComplexSlicer.Slice(polygon, new List <Vector2f> (polygonSlice.pointsList));


        //if (result.polygons.Count < 1)
        //debug用 消しても大丈夫そう
        //  Debug.LogError ("Slicer2D: Returns Empty Polygon Slice");

        Slicer2D.complexSliceType = tempSliceType;

        return(result);
    }
Exemplo n.º 6
0
    // Polygon Slice - TODO: Return No Polygon if it's eaten by polygon slice
    static public Slice2D Slice(Polygon polygon, Polygon polygonSlice)
    {
        Slice2D result = Slice2D.Create();

        Slicer2D.SliceType tempSliceType = Slicer2D.complexSliceType;
        Slicer2D.complexSliceType = Slicer2D.SliceType.SliceHole;

        polygonSlice.Normalize();
        polygon.Normalize();

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

        if (polygon.PolyInPoly(polygonSlice) == true)
        {
            polygon.AddHole(polygonSlice);
            result.AddPolygon(polygon);
            return(result);
        }

        // Act as Regular Slice
        Vector2f startPoint = null;

        foreach (Vector2f id in polygonSlice.pointsList)
        {
            if (polygon.PointInPoly(id) == false)
            {
                startPoint = id;
                break;
            }
        }


        if (startPoint == null)
        {
            Debug.LogError("Slicer2D: Starting Point Error In PolygonSlice");
            return(result);
        }

        polygonSlice.pointsList = VectorList2f.GetListStartingPoint(polygonSlice.pointsList, startPoint);

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

        polygonSlice.AddPoint(startPoint);

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

        // Slice More Times?
        result = ComplexSlicer.Slice(polygon, new List <Vector2f> (polygonSlice.pointsList));

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

        Slicer2D.complexSliceType = tempSliceType;

        return(result);
    }
Exemplo n.º 7
0
    static public Slice2D Slice(Polygon polygon, List <Vector2f> slice)
    {
        Slice2D result = Slice2D.Create();

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

        // Normalize into clockwise
        polygon.Normalize();

        if (Slicer2D.complexSliceType != Slicer2D.SliceType.Regular)
        {
            result = SlicePolygonInside(polygon, slice);
            if (result.polygons.Count > 0)
            {
                return(result);
            }
        }

        // Optimization (holes?)
        // if (polygon.SliceIntersectPoly (slice) == false)
        //	return(result);

        List <List <Vector2f> > slices = new List <List <Vector2f> >();

        bool entered = polygon.PointInPoly(slice.First());

        List <Vector2f> currentSlice = new List <Vector2f> ();

        foreach (Pair2f pair in Pair2f.GetList(slice, false))
        {
            List <Vector2f> stackList = polygon.GetListSliceIntersectPoly(pair);
            stackList = VectorList2f.GetListSortedToPoint(stackList, pair.A);

            foreach (Vector2f id in stackList)
            {
                if (entered == true)
                {
                    currentSlice.Add(id);
                    slices.Add(currentSlice);
                }
                else
                {
                    currentSlice = new List <Vector2f> ();
                    currentSlice.Add(id);
                }
                entered = !entered;
            }

            if (entered == true)
            {
                currentSlice.Add(pair.B);
            }
        }

        // Adjusting split lines before performing convex split
        result.AddPolygon(polygon);

        foreach (List <Vector2f> id in slices)
        {
            if (id.Count > 1)
            {
                foreach (Vector2f p in id)
                {
                    result.AddCollision(p);
                }

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

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

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

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

                        // If it's possible to perform convex split, remove parent polygon from result list
                        result.RemovePolygon(poly);
                    }
                }
            }
        }
        result.RemovePolygon(polygon);
        return(result);
    }
Exemplo n.º 8
0
    static private Slice2D SliceWithOneHole(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice)
    {
        Slice2D result = Slice2D.Create();

        Polygon holeA    = polygon.PointInHole(slice.First());
        Polygon holeB    = polygon.PointInHole(slice.Last());
        Polygon holePoly = (holeA != null) ? holeA : holeB;


        if (polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false)
        {
            if (holeA == holeB)
            {
                if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular)
                {
                    return(result);
                }

                if (holeA == null)
                {
                    Debug.LogError("Slicer2D: This happened when collider had a lot of paths but they were not holes");
                    return(result);
                }

                List <Vector2f> slice2 = new List <Vector2f> (slice);

                Polygon polyA = new Polygon(polygon.pointsList);
                Polygon polyB = new Polygon(slice);
                Polygon polyC = new Polygon(slice2);

                // Get First Point - NOT FINISHED WITH INTERSECTION
                int             Add;
                List <Vector2f> list;
                List <Pair2f>   iterateList = Pair2f.GetList(holeA.pointsList);

                Add  = 0;
                list = new List <Vector2f> ();
                foreach (Pair2f pair in iterateList)
                {
                    List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice);
                    if (intersect.Count > 0)
                    {
                        Add += intersect.Count;
                    }

                    if (Add == 1)
                    {
                        list.Add(pair.B);
                    }
                }

                if (list.Count > 0)
                {
                    if (Vector2f.Distance(list.First(), slice.First()) < Vector2f.Distance(list.First(), slice.Last()))
                    {
                        slice.Reverse();
                    }

                    polyB.AddPoints(list);
                }

                Add  = 0;
                list = new List <Vector2f> ();
                foreach (Pair2f pair in iterateList)
                {
                    List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice2);
                    if (intersect.Count > 0)
                    {
                        Add += intersect.Count;
                    }

                    if (Add == 2)
                    {
                        list.Add(pair.B);
                    }
                }

                foreach (Pair2f pair in iterateList)
                {
                    List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice2);
                    if (intersect.Count > 0)
                    {
                        Add += intersect.Count;
                    }

                    if (Add == 2)
                    {
                        list.Add(pair.B);
                    }
                }

                if (list.Count > 0)
                {
                    if (Vector2f.Distance(list.First(), slice2.First()) < Vector2f.Distance(list.First(), slice2.Last()))
                    {
                        slice2.Reverse();
                    }

                    polyC.AddPoints(list);
                }

                if (polyB.GetArea() > polyC.GetArea())
                {
                    Polygon swap = polyB;
                    polyB = polyC;
                    polyC = swap;
                }

                // Add holes to new created polygon
                foreach (Polygon poly in polygon.holesList)
                {
                    if (poly != holeA && polyB.PolyInPoly(poly) == true)
                    {
                        polyB.AddHole(poly);
                    }
                }

                if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole)
                {
                    result.AddPolygon(polyB);
                }

                polyA.AddHole(polyC);

                // Adds polygons if they are not in the hole
                foreach (Polygon poly in polygon.holesList)                 // Check for errors?
                {
                    if (poly != holeA && polyC.PolyInPoly(poly) == false)
                    {
                        polyA.AddHole(poly);
                    }
                }

                result.AddPolygon(polyA);
                return(result);
            }
            else if (holePoly != null)
            {
                Polygon polyA = new Polygon();
                Polygon polyB = new Polygon(holePoly.pointsList);
                polyB.pointsList.Reverse();

                List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(polygon.pointsList, slice);
                List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(polyB.pointsList, slice);

                if (pointsA.Count < 1)
                {
                    Debug.LogError("Slicer2D: " + pointsA.Count + " " + polygon.pointsList.Count);
                }

                polyA.AddPoints(pointsA);

                if (collisionSlice.Count > 0)
                {
                    // pointsA empty
                    if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First()))
                    {
                        collisionSlice.Reverse();
                    }

                    polyA.AddPoints(collisionSlice);
                }

                polyA.AddPoints(pointsB);

                if (collisionSlice.Count > 0)
                {
                    collisionSlice.Reverse();
                    polyA.AddPoints(collisionSlice);
                }

                foreach (Polygon poly in polygon.holesList)                 // Check for errors?
                {
                    if (poly != holePoly)
                    {
                        polyA.AddHole(poly);
                    }
                }

                result.AddPolygon(polyA);

                return(result);
            }
        }

        return(result);
    }
Exemplo n.º 9
0
    // Slice From Point
    static public Slice2D SliceFromPoint(Polygon polygon, Vector2f point, float rotation)
    {
        Slice2D result = Slice2D.Create();

        // Normalize into clockwise
        polygon.Normalize();

        Vector2f sliceA = new Vector2f(point);
        Vector2f sliceB = new Vector2f(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 <Vector2f> intersectionsA = polygon.GetListSliceIntersectPoly(new Pair2f(point, sliceA));
        List <Vector2f> intersectionsB = polygon.GetListSliceIntersectPoly(new Pair2f(point, sliceB));

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

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

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

        result.AddPolygon(polygon);

        foreach (Pair2f id in collisionList)
        {
            // Sclice line points generated from intersections list
            Vector2f vec0 = new Vector2f(id.A);
            Vector2f vec1 = new Vector2f(id.B);

            float rot = Vector2f.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 <Polygon> temp = new List <Polygon>(result.polygons);           // necessary?
            foreach (Polygon poly in temp)
            {
                // NO, that's the problem
                Slice2D resultList = LinearSlicer.Slice(poly, new Pair2f(vec0, vec1));

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

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