예제 #1
0
    //if (slice.Count == 2) return(PolygonSimpleSlicer.SplitLineConcave (polygon, new Pair2D (slice.First (), slice.Last ())));
    static private Slice2D SingleSlice(Polygon2D polygon, List <Vector2D> slice)
    {
        Slice2D result = Slice2D.Create(null, slice);

        // Change
        if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular)
        {
            if (Math2D.SliceIntersectItself(slice))
            {
                if (Slicer2D.Debug.enabled)
                {
                    Debug.LogWarning("Slicer2D: Slice Intersect Itself In Regular Mode");
                }
                return(result);
            }
        }

        if (polygon.PointInPoly(slice.First()) == true || polygon.PointInPoly(slice.Last()) == true)
        {
            return(result);
        }

        slice = new List <Vector2D> (slice);

        ComplexCollision collisionSlice = new ComplexCollision(polygon, slice);

        if (collisionSlice.error)
        {
            // When this happens?
            if (Slicer2D.Debug.enabled)
            {
                Debug.LogWarning("Slicer2D: Unexpected Error 2");
            }
            return(result);
        }

        List <Polygon2D> intersectHoles = polygon.GetListSliceIntersectHoles(slice);

        switch (intersectHoles.Count)
        {
        case 0:
            if (collisionSlice.collisionCount == 2)
            {
                return(SliceWithoutHoles(polygon, slice, collisionSlice));
            }
            break;

        case 1:
            return(SliceWithOneHole(polygon, slice, collisionSlice));

        case 2:
            return(SliceWithTwoHoles(polygon, slice, collisionSlice));

        default:
            break;
        }

        return(result);
    }
예제 #2
0
            static public Slice2D Slice(Polygon2D polygon, List <Vector2D> slice, ComplexCollision collisionSlice)
            {
                Slice2D result = Slice2D.Create(null, slice);

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

                if (holePoly == null)
                {
                    if (Slicer2D.Debug.enabled)
                    {
                        Debug.LogWarning("Slicer2D: Slice is not in the hole (SliceWithOneHole)");
                    }
                    return(result);
                }

                List <Vector2D> slices = new List <Vector2D>(collisionSlice.GetPointsInsidePlus());

                // If any slice endings is not outside polygon
                if ((polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false) == false)
                {
                    return(result);
                }

                // Slicing Into The Same Hole
                if (holeA == holeB)
                {
                    if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular)
                    {
                        return(result);
                    }

                    result = SliceIntoSameHole(polygon, holePoly, slice, collisionSlice);
                    result.AddSlice(slices);

                    // Slicing From Outside To Hole
                }
                else if (holePoly != null)
                {
                    result = SliceFromOutsideToHole(polygon, holePoly, slice, collisionSlice);
                    result.AddSlice(slices);
                }

                return(result);
            }
예제 #3
0
    static private Slice2D SliceWithoutHoles(Polygon2D polygon, List <Vector2D> slice, ComplexCollision collisionSlice)
    {
        Slice2D result = Slice2D.Create(null, slice);

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

        Polygon2D currentPoly = polyA;

        List <Vector2D> slices = new List <Vector2D>(collisionSlice.GetPointsInsidePlus());

        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();
                    }

                    //currentPoly.AddPoint (first);

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

                        currentPoly.AddPoints(collisionSlice.GetPointsInsidePlus());
                    }
                    /////

                    //currentPoly.AddPoint (last);

                    currentPoly = polyB;

                    if (collisionSlice.GetPointsInsidePlus().Count > 0)
                    {
                        currentPoly.AddPoints(collisionSlice.GetPointsInsidePlus());
                    }

                    //currentPoly.AddPoint (last);
                    //currentPoly.AddPoint (first);

                    currentPoly = polyA;
                }

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

                    //currentPoly.AddPoint (intersection);

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

                        currentPoly.AddPoints(collisionSlice.GetPointsInsidePlus());
                    }
                    /////

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

                    //currentPoly.AddPoint (intersection);
                }
            }

            currentPoly.AddPoint(p.B);
        }

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

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

        result.AddSlice(slices);
        return(result);
    }
예제 #4
0
    static private Slice2D SliceWithTwoHoles(Polygon2D polygon, List <Vector2D> slice, ComplexCollision collisionSlice)
    {
        Slice2D result = Slice2D.Create(null, slice);

        if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular)
        {
            return(result);
        }

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

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

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

        List <Vector2D> slices = new List <Vector2D>(collisionSlice.GetPointsInsidePlus());

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

        polyA.AddPoints(pointsA);

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

            polyA.AddPoints(collisionSlice.GetPointsInside());
        }

        polyA.AddPoints(pointsB);

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

            polyA.AddPoints(collisionSlice.GetPointsInside());
        }

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

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

        result.AddSlice(slices);
        return(result);
    }
예제 #5
0
    static private Slice2D SliceWithOneHole(Polygon2D polygon, List <Vector2D> slice, ComplexCollision collisionSlice)
    {
        Slice2D result = Slice2D.Create(null, slice);

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

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

        List <Vector2D> slices = new List <Vector2D>(collisionSlice.GetPointsInsidePlus());

        if (polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false)
        {
            // Slicing Into The Same Hole
            if (holeA == holeB)
            {
                if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular)
                {
                    return(result);
                }

                if (collisionSlice.polygonCollisionPairs.Count == 1)
                {
                    Polygon2D slicePoly = new Polygon2D(collisionSlice.GetPointsInsidePlus());

                    Polygon2D newHole = new Polygon2D();
                    if (slicePoly.PolyInPoly(holePoly))
                    {
                        newHole = slicePoly;
                    }
                    else
                    {
                        foreach (Pair2D pair in Pair2D.GetList(holePoly.pointsList))
                        {
                            newHole.AddPoint(pair.A);

                            if (Vector2D.Distance(pair.A, collisionSlice.Last()) < Vector2D.Distance(pair.A, collisionSlice.First()))
                            {
                                collisionSlice.Reverse();
                            }

                            if (Math2D.LineIntersectSlice(pair, slice))
                            {
                                newHole.AddPoints(collisionSlice.GetPoints());
                            }
                        }
                    }

                    Polygon2D polygonA = new Polygon2D(polygon.pointsList);
                    polygonA.AddHole(newHole);

                    // Adds polygons if they are not in the hole
                    foreach (Polygon2D poly in polygon.holesList)                       // Check for errors?
                    {
                        if (poly != holePoly && polygonA.PolyInPoly(poly) == true)
                        {
                            polygonA.AddHole(poly);
                        }
                    }

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

                    result.AddPolygon(polygonA);

                    result.AddSlice(slices);

                    return(result);
                }
                else
                {
                    Polygon2D polyA    = new Polygon2D(polygon.pointsList);
                    Polygon2D newHoleA = new Polygon2D();
                    Polygon2D newHoleB = new Polygon2D();

                    List <Pair2D> iterateList = Pair2D.GetList(holePoly.pointsList);

                    bool addPoints = false;

                    foreach (Pair2D pair in iterateList)
                    {
                        List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice);

                        switch (addPoints)
                        {
                        case false:
                            if (intersect.Count > 0)
                            {
                                addPoints = true;
                            }

                            break;

                        case true:
                            newHoleA.AddPoint(pair.A);

                            if (intersect.Count > 0)
                            {
                                addPoints = false;

                                if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First()))
                                {
                                    collisionSlice.Reverse();
                                }
                                newHoleA.AddPoints(collisionSlice.GetPointsInsidePlus());
                            }
                            break;
                        }
                    }

                    addPoints = true;
                    foreach (Pair2D pair in iterateList)
                    {
                        List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice);

                        switch (addPoints)
                        {
                        case false:
                            if (intersect.Count > 0)
                            {
                                addPoints = true;
                            }

                            break;

                        case true:
                            newHoleB.AddPoint(pair.A);

                            if (intersect.Count > 0)
                            {
                                addPoints = false;

                                if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First()))
                                {
                                    collisionSlice.Reverse();
                                }
                                newHoleB.AddPoints(collisionSlice.GetPointsInsidePlus());
                            }
                            break;
                        }
                    }

                    if (newHoleB.GetArea() > newHoleA.GetArea())
                    {
                        Polygon2D tempPolygon = newHoleA;
                        newHoleA = newHoleB;
                        newHoleB = tempPolygon;
                    }

                    polyA.AddHole(newHoleA);

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

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

                    result.AddPolygon(polyA);

                    result.AddSlice(slices);
                    return(result);
                }

                // Slicing From Outside To Hole
            }
            else if (holePoly != null)
            {
                Polygon2D polyA = new Polygon2D();
                Polygon2D polyB = new Polygon2D(holePoly.pointsList);
                polyB.pointsList.Reverse();

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

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

                polyA.AddPoints(pointsA);

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

                    polyA.AddPoints(collisionSlice.GetPointsInside());
                }

                polyA.AddPoints(pointsB);

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

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

                result.AddPolygon(polyA);

                result.AddSlice(slices);
                return(result);
            }
        }

        return(result);
    }
예제 #6
0
            static public Slice2D SliceIntoSameHole(Polygon2D polygon, Polygon2D holePoly, List <Vector2D> slice, ComplexCollision collisionSlice)
            {
                Slice2D result = Slice2D.Create(null, slice);

                // Slice Into Same Pair
                if (collisionSlice.polygonCollisionPairs.Count == 1)
                {
                    Polygon2D slicePoly = new Polygon2D(collisionSlice.GetPointsInsidePlus());

                    Polygon2D newHole = new Polygon2D();
                    if (slicePoly.PolyInPoly(holePoly))
                    {
                        newHole = slicePoly;
                    }
                    else
                    {
                        foreach (Pair2D pair in Pair2D.GetList(holePoly.pointsList))
                        {
                            newHole.AddPoint(pair.A);

                            if (Vector2D.Distance(pair.A, collisionSlice.Last()) < Vector2D.Distance(pair.A, collisionSlice.First()))
                            {
                                collisionSlice.Reverse();
                            }

                            if (Math2D.LineIntersectSlice(pair, slice))
                            {
                                newHole.AddPoints(collisionSlice.GetPoints());
                            }
                        }
                    }

                    Polygon2D polygonA = new Polygon2D(polygon.pointsList);
                    polygonA.AddHole(newHole);

                    // Adds polygons if they are not in the hole
                    foreach (Polygon2D poly in polygon.holesList)                       // Check for errors?
                    {
                        if (poly != holePoly && polygonA.PolyInPoly(poly) == true)
                        {
                            polygonA.AddHole(poly);
                        }
                    }

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

                    result.AddPolygon(polygonA);

                    return(result);

                    // Slice Into Different Pair
                }
                else
                {
                    Polygon2D polyA    = new Polygon2D(polygon.pointsList);
                    Polygon2D newHoleA = new Polygon2D();
                    Polygon2D newHoleB = new Polygon2D();

                    List <Pair2D> iterateList = Pair2D.GetList(holePoly.pointsList);

                    bool addPoints = false;

                    foreach (Pair2D pair in iterateList)
                    {
                        List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice);

                        switch (addPoints)
                        {
                        case false:
                            if (intersect.Count > 0)
                            {
                                addPoints = true;
                            }

                            break;

                        case true:
                            newHoleA.AddPoint(pair.A);

                            if (intersect.Count > 0)
                            {
                                addPoints = false;

                                if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First()))
                                {
                                    collisionSlice.Reverse();
                                }
                                newHoleA.AddPoints(collisionSlice.GetPointsInsidePlus());
                            }
                            break;
                        }
                    }

                    addPoints = true;
                    foreach (Pair2D pair in iterateList)
                    {
                        List <Vector2D> intersect = Math2D.GetListLineIntersectSlice(pair, slice);

                        switch (addPoints)
                        {
                        case false:
                            if (intersect.Count > 0)
                            {
                                addPoints = true;
                            }

                            break;

                        case true:
                            newHoleB.AddPoint(pair.A);

                            if (intersect.Count > 0)
                            {
                                addPoints = false;

                                if (Vector2D.Distance(intersect[0], collisionSlice.Last()) < Vector2D.Distance(intersect[0], collisionSlice.First()))
                                {
                                    collisionSlice.Reverse();
                                }
                                newHoleB.AddPoints(collisionSlice.GetPointsInsidePlus());
                            }
                            break;
                        }
                    }

                    if (newHoleB.GetArea() > newHoleA.GetArea())
                    {
                        Polygon2D tempPolygon = newHoleA;
                        newHoleA = newHoleB;
                        newHoleB = tempPolygon;
                    }

                    polyA.AddHole(newHoleA);

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

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

                    result.AddPolygon(polyA);

                    return(result);
                }
            }
예제 #7
0
            static public Slice2D SliceFromOutsideToHole(Polygon2D polygon, Polygon2D holePoly, List <Vector2D> slice, ComplexCollision collisionSlice)
            {
                Slice2D result = Slice2D.Create(null, slice);

                Polygon2D polyA = new Polygon2D();
                Polygon2D polyB = new Polygon2D(holePoly.pointsList);

                polyB.pointsList.Reverse();

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

                if (pointsA.Count < 1)
                {
                    if (Slicer2D.Debug.enabled)
                    {
                        Debug.LogWarning("Slicer2D: Not enough of slice intersections with polygon (SliceWithOneHole)");
                    }
                }

                polyA.AddPoints(pointsA);

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

                    polyA.AddPoints(collisionSlice.GetPointsInside());
                }

                polyA.AddPoints(pointsB);

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

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

                result.AddPolygon(polyA);
                return(result);
            }
예제 #8
0
        static private Slice2D SingleSlice(Polygon2D polygon, ComplexSlicerSplit split)
        {
            Slice2D result = Slice2D.Create(null, split.points);

            // Change
            if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular)
            {
                if (Math2D.SliceIntersectItself(split.points))
                {
                    if (Slicer2D.Debug.enabled)
                    {
                        Debug.LogWarning("Slicer2D: Slice Intersect Itself In Regular Mode");
                    }
                    return(result);
                }
            }

            // Start and End of slice should be outside the polygon
            if (polygon.PointInPoly(split.points.First()) == true || polygon.PointInPoly(split.points.Last()) == true)
            {
                return(result);
            }

            List <Vector2D> slice = new List <Vector2D> (split.points);

            if (split.type == ComplexSlicerSplit.Type.SingleVertexCollision)
            {
                Debug.Log("Single Vertex Collision");

                return(result);
            }

            ComplexCollision collisionSlice = new ComplexCollision(polygon, slice);

            if (collisionSlice.error)
            {
                if (Slicer2D.Debug.enabled)
                {
                    Debug.LogWarning("Slicer2D: Complex Collision Error");
                }
                return(result);
            }

            List <Polygon2D> intersectHoles = polygon.GetListSliceIntersectHoles(slice);

            switch (intersectHoles.Count)
            {
            case 0:
                if (collisionSlice.collisionCount == 2)
                {
                    return(SliceWithoutHoles.Slice(polygon, slice, collisionSlice));
                }
                break;

            case 1:
                return(SliceWithOneHole.Slice(polygon, slice, collisionSlice));

            case 2:
                return(SliceWithTwoHoles.Slice(polygon, slice, collisionSlice));

            default:
                break;
            }

            return(result);
        }