Пример #1
0
        //public void DebugOut()
        //{
        //   // String strOut = new string("r");

        //    String strOut = String.Format("Count {0} \n", Count);
        //    System.Diagnostics.Trace.TraceInformation(strOut);

        //    for (int i = 0; i < Count; i++)
        //    {
        //        String strOut0 = String.Format("{0}: Count {1} ", i, this[i].Count);
        //      //  System.Diagnostics.Trace.TraceInformation(strOut);

        //        //for (int j = 0 ; j < this->GetAt(i)->size(); j++)
        //        //{
        //        //	C2DPoint p1 = this->GetAt(i)->GetAt(j)->GetPointFrom();
        //        //	sprintf(buff, "x:%f  y:%f", p1.x, p1.y);
        //        //}

        //        C2DPoint p1 = this[i][0].GetPointFrom();
        //        String strOut1 = String.Format("From x:{0}  y:{1}", p1.x, p1.y);
        //      //  System.Diagnostics.Trace.TraceInformation(strOut);

        //        C2DPoint p2 = this[i][this[i].Count - 1].GetPointTo();
        //        String strOut2 = String.Format("To x:{0}  y:{1} \n", p2.x, p2.y);
        //        System.Diagnostics.Trace.TraceInformation(strOut0 + strOut1 + strOut2);
        //    }
        //}



        /// <summary>
        /// Adds all the routes from the other to this if the join a routes in this.
        /// </summary>
        /// <param name="Other">The other set.</param>
        public void AddJoining(C2DLineBaseSetSet Other)
        {
            C2DLineBaseSetSet Temp = new C2DLineBaseSetSet();

            while (Other.Count > 0)
            {
                C2DLineBaseSet pLast = Other.ExtractAt(Other.Count - 1);

                int i = 0;
                while (i < Count)
                {
                    if (!this[i].IsClosed(true) && this[i].AddIfCommonEnd(pLast))
                    {
                        pLast = null;
                        i    += Count;  // escape
                    }

                    i++;
                }

                if (pLast != null)
                {
                    Temp.Add(pLast);
                }
            }

            while (Temp.Count > 0)
            {
                Other.Add(Temp.ExtractAt(Temp.Count - 1));
            }
        }
Пример #2
0
        /// <summary>
        /// Returns the routes (multiple lines or part polygons) either inside or
        /// outside the polygons provided. These are based on the intersections
        /// of the 2 polygons e.g. the routes / part polygons of one inside or
        /// outside the other.
        /// </summary>
        /// <param name="Poly1">The first polygon.</param>
        /// <param name="bP1RoutesInside">True if routes inside the second polygon are
        /// required for the first polygon.</param>
        /// <param name="Poly2">The second polygon.</param>
        /// <param name="bP2RoutesInside">True if routes inside the first polygon are
        /// required for the second polygon.</param>
        /// <param name="Routes1">Output. Set of lines for the first polygon.</param>
        /// <param name="Routes2">Output. Set of lines for the second polygon.</param>
        public static void GetRoutes(C2DPolyBase Poly1, bool bP1RoutesInside,
                                     C2DPolyBase Poly2, bool bP2RoutesInside,
                                     C2DLineBaseSetSet Routes1, C2DLineBaseSetSet Routes2)
        {
            // Set up a collection of intersected points, and corresponding indexes.
            var IntPoints = new C2DPointSet();
            var Indexes1  = new List <int>();
            var Indexes2  = new List <int>();

            // Use the line collections in each shape to find the intersections between them.
            Poly1.Lines.GetIntersections(Poly2.Lines, IntPoints,
                                         Indexes1, Indexes2,
                                         Poly1.BoundingRect, Poly2.BoundingRect);
            // Make a copy of the point set because this will be sorted by line index in the
            // Get routes function later. We need an unsorted set for each polygon.
            var IntPointsCopy = new C2DPointSet();

            IntPointsCopy.MakeCopy(IntPoints);

            // Find out whether the first poly starts inside the second.
            bool bP1StartInside = Poly2.Contains(Poly1.Lines[0].GetPointFrom());
            // Find out if poly 2 starts inside poly 1.
            bool bP2StartInside = Poly1.Contains(Poly2.Lines[0].GetPointFrom());

            if (IntPoints.Count == 0 && !bP1StartInside && !bP2StartInside)
            {
                return; // No interaction between the 2.
            }
            // Get the routes of poly 1 inside / outside the other, passing the unsorted
            // intersection points and polygon1 intersection indexes.
            Poly1.GetRoutes(IntPoints, Indexes1, Routes1, bP1StartInside, bP1RoutesInside);
            // Do the same for poly 2 but pass it the unsorted copy of the intersection points
            // So that they correspond to the indexes.
            Poly2.GetRoutes(IntPointsCopy, Indexes2, Routes2, bP2StartInside, bP2RoutesInside);
        }
Пример #3
0
        /// <summary>
        /// Adds the routes in the other set that are closed.
        /// </summary>
        /// <param name="Other">The other set.</param>
        /// <param name="bEndsOnly">True if only the ends require checking.</param>
        public void AddClosed(C2DLineBaseSetSet Other, bool bEndsOnly)
        {
            C2DLineBaseSetSet Temp = new C2DLineBaseSetSet();

            while (Other.Count > 0)
            {
                C2DLineBaseSet pLast = Other.ExtractAt(Other.Count - 1);
                if (pLast.IsClosed(bEndsOnly))
                {
                    this.Add(pLast);
                }
                else
                {
                    Temp.Add(pLast);
                }
            }

            while (Temp.Count > 0)
            {
                Other.Add(Temp.ExtractAt(Temp.Count - 1));
            }
        }
Пример #4
0
        /// <summary>
        /// Merges the joining routes together if there are any.
        /// </summary>
        public void MergeJoining()
        {
            C2DLineBaseSetSet Temp = new C2DLineBaseSetSet();

            while (Count > 0)
            {
                // pop the last one.
                C2DLineBaseSet pLast = this[Count - 1];
                this.RemoveAt(Count - 1);

                if (!pLast.IsClosed(true))
                {
                    int i = 0;
                    while (i < Count)
                    {
                        if (!this[i].IsClosed(true))
                        {
                            if (this[i].AddIfCommonEnd(pLast))
                            {
                                pLast = null;
                                i    += Count;  // escape
                            }
                        }

                        i++;
                    }
                }

                if (pLast != null)
                {
                    Temp.Add(pLast);
                }
            }

            this.ExtractAllOf(Temp);
        }
Пример #5
0
        /// <summary>
        /// Gets the boolean operation with the other. e.g. union / intersection.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        /// <param name="HoledPolys">The set to recieve the result.</param>
        /// <param name="bThisInside">The flag to indicate routes inside.</param>
        /// <param name="bOtherInside">The flag to indicate routes inside for the other.</param>
        /// <param name="grid">The degenerate settings.</param>
        public void GetBoolean(C2DPolyBase Other, List <C2DHoledPolyBase> HoledPolys,
                               bool bThisInside, bool bOtherInside,
                               CGrid grid)
        {
            if (BoundingRect.Overlaps(Other.BoundingRect))
            {
                switch (grid.DegenerateHandling)
                {
                case CGrid.eDegenerateHandling.None:
                {
                    var Routes1 = new C2DLineBaseSetSet();
                    var Routes2 = new C2DLineBaseSetSet();
                    C2DPolyBase.GetRoutes(this, bThisInside, Other, bOtherInside, Routes1, Routes2);
                    Routes1.ExtractAllOf(Routes2);

                    if (Routes1.Count > 0)
                    {
                        // Add all the joining routes together to form closed routes
                        Routes1.MergeJoining();
                        // Set up some temporary polygons.
                        var Polygons = new List <C2DPolyBase>();
                        // Turn the routes into polygons.
                        for (var i = Routes1.Count - 1; i >= 0; i--)
                        {
                            if (Routes1[i].IsClosed(true) && Routes1[i].Count > 2)
                            {
                                Polygons.Add(new C2DPolyBase());
                                Polygons[Polygons.Count - 1].CreateDirect(Routes1[i]);
                            }
                            else
                            {
                                //   Debug.Assert(false);
                                grid.LogDegenerateError();
                            }
                        }


                        // Set up some temporary holed polygons
                        var NewComPolys = new C2DHoledPolyBaseSet();
                        // Turn the set of polygons into holed polygons. Not needed for intersection.
                        if (!(bThisInside && bOtherInside))
                        {
                            C2DHoledPolyBase.PolygonsToHoledPolygons(NewComPolys, Polygons);
                            if (NewComPolys.Count != 1)
                            {
                                //   Debug.Assert(false);
                                grid.LogDegenerateError();
                            }
                        }
                        else
                        {
                            for (var i = 0; i < Polygons.Count; i++)
                            {
                                HoledPolys.Add(new C2DHoledPolyBase(Polygons[i]));
                            }
                        }

                        // Now add them all to the provided set.
                        for (var i = 0; i < NewComPolys.Count; i++)
                        {
                            HoledPolys.Add(NewComPolys[i]);
                        }
                    }
                }
                break;

                case CGrid.eDegenerateHandling.RandomPerturbation:
                {
                    var OtherCopy = new C2DPolyBase(Other);
                    OtherCopy.RandomPerturb();
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(OtherCopy, HoledPolys, bThisInside, bOtherInside, grid);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.RandomPerturbation;
                }
                break;

                case CGrid.eDegenerateHandling.DynamicGrid:
                {
                    var Rect = new C2DRect();
                    if (this.BoundingRect.Overlaps(Other.BoundingRect, Rect))
                    {
                        var dOldGrid = grid.GridSize;
                        grid.SetToMinGridSize(Rect, false);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                        GetBoolean(Other, HoledPolys, bThisInside, bOtherInside, grid);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.DynamicGrid;
                    }
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGrid:
                {
                    var P1 = new C2DPolyBase(this);
                    var P2 = new C2DPolyBase(Other);
                    P1.SnapToGrid(grid);
                    P2.SnapToGrid(grid);
                    var V1            = new C2DVector(P1.BoundingRect.TopLeft, P2.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;                     // ensure it snaps back to original grid positions.
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;          // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.

                    P2.Move(V1);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    P1.GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:
                {
                    var P2            = new C2DPolyBase(Other);
                    var V1            = new C2DVector(this.BoundingRect.TopLeft, P2.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;                     // ensure it snaps back to original grid positions.
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;     // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.

                    P2.Move(V1);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
                }
                break;
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Returns the routes (collection of lines and sublines) either inside or outside another
        /// Given the intersection points.
        /// </summary>
        /// <param name="IntPts">The intersection points of this with the other polygon.</param>
        /// <param name="IntIndexes">The corresponding line indexes.</param>
        /// <param name="Routes">Output. The routes to get the result.</param>
        /// <param name="bStartInside">True if this polygon starts inside the other.</param>
        /// <param name="bRoutesInside">True if we require routes of this polygon inside the other.</param>
        public void GetRoutes(C2DPointSet IntPts, List <int> IntIndexes,
                              C2DLineBaseSetSet Routes, bool bStartInside, bool bRoutesInside)
        {
            // Make sure the intersection indexes and points are the same size.
            if (IntIndexes.Count != IntPts.Count)
            {
                Debug.Assert(false);
                return;
            }
            // Set up a new collection of routes.
            var NewRoutes = new C2DLineBaseSetSet();

            // If the polygon has no points then return.
            if (_Lines.Count < 1)
            {
                return;
            }
            // Sort the intersections by index so we can go through them in order.
            IntPts.SortByIndex(IntIndexes);

            // Set the inside / outside flag to the same as the start inside / outside flag.
            var bInside = bStartInside;

            // If we are inside and want route inside or outside and want routes outside then add a new route.
            if (bInside == bRoutesInside)
            {
                NewRoutes.Add(new C2DLineBaseSet());
            }

            // The current index of the intersects.
            var usCurrentIntIndex = 0;

            // cycle through the lines on the polygon.
            for (var i = 0; i < Lines.Count; i++)
            {
                // Set up a list of intersection points on this line only.
                var IntsOnLine = new C2DPointSet();
                // Cycle through all intersections on this line (leaving the usCurrentIntIndex at the next intersected line).
                while (usCurrentIntIndex < IntIndexes.Count && IntIndexes[usCurrentIntIndex] == i)
                {
                    // Add a copy of the points on this line that are intersections
                    IntsOnLine.AddCopy(IntPts[usCurrentIntIndex]);
                    usCurrentIntIndex++;
                }

                // If the line in question intersects the other poly then we have left / entered.
                if (IntsOnLine.Count > 0)
                {
                    var SubLines = new C2DLineBaseSet();
                    Lines[i].GetSubLines(IntsOnLine, SubLines);

                    while (SubLines.Count > 1)
                    {
                        if (bInside == bRoutesInside)
                        {
                            // We have 1. Left and want route in. OR 2. Entered and want routes out.
                            NewRoutes[NewRoutes.Count - 1].Add(SubLines.ExtractAt(0));
                            bInside = true ^ bRoutesInside;
                        }
                        else
                        {
                            NewRoutes.Add(new C2DLineBaseSet());
                            bInside = false ^ bRoutesInside;
                            SubLines.RemoveAt(0);
                        }
                    }
                    if (bInside == bRoutesInside)
                    {
                        NewRoutes[NewRoutes.Count - 1].Add(SubLines.ExtractAt(SubLines.Count - 1));
                    }
                    else
                    {
                        SubLines.RemoveAt(SubLines.Count - 1);
                    }
                }
                // Otherwise, if we are e.g. inside and want routes in the keep adding the end poitn of the line.
                else if (bInside == bRoutesInside)
                {
                    NewRoutes[NewRoutes.Count - 1].AddCopy(Lines[i]);
                }
            }
            // Put all the new routes into the provided collection.
            Routes.ExtractAllOf(NewRoutes);
        }
Пример #7
0
        /// <summary>
        /// Returns the routes (multiple lines or part polygons) either inside or
        /// outside the polygons provided. These are based on the intersections
        /// of the 2 polygons e.g. the routes / part polygons of one inside or
        /// outside the other.
        /// </summary>
        /// <param name="Poly1">The first polygon.</param>
        /// <param name="bP1RoutesInside">True if routes inside the second polygon are
        /// required for the first polygon.</param>
        /// <param name="Poly2">The second polygon.</param>
        /// <param name="bP2RoutesInside">True if routes inside the first polygon are
        /// required for the second polygon.</param>
        /// <param name="Routes1">Output. Set of lines for the first polygon.</param>
        /// <param name="Routes2">Output. Set of lines for the second polygon.</param>
        /// <param name="CompleteHoles1">Output. Complete holes for the first polygon.</param>
        /// <param name="CompleteHoles2">Output. Complete holes for the second polygon.</param>
        /// <param name="grid">Contains the degenerate handling settings.</param>
        public static void GetRoutes(C2DHoledPolyBase Poly1, bool bP1RoutesInside,
                                     C2DHoledPolyBase Poly2, bool bP2RoutesInside,
                                     C2DLineBaseSetSet Routes1, C2DLineBaseSetSet Routes2,
                                     List <C2DPolyBase> CompleteHoles1, List <C2DPolyBase> CompleteHoles2,
                                     CGrid grid)
        {
            if (Poly1.Rim.Lines.Count == 0 || Poly2.Rim.Lines.Count == 0)
            {
                Debug.Assert(false, "Polygon with no lines");
                return;
            }

            var IntPointsTemp = new C2DPointSet();
            var IntPointsRim1 = new C2DPointSet();
            var IntPointsRim2 = new C2DPointSet();
            var IndexesRim1   = new List <int>();
            var IndexesRim2   = new List <int>();


            var IntPoints1AllHoles = new List <C2DPointSet>();
            var IntPoints2AllHoles = new List <C2DPointSet>();
            var Indexes1AllHoles   = new List <List <int> >();
            var Indexes2AllHoles   = new List <List <int> >();
            //    std::vector<C2DPointSet* > IntPoints1AllHoles, IntPoints2AllHoles;
            //   std::vector<CIndexSet*> Indexes1AllHoles, Indexes2AllHoles;

            var usP1Holes = Poly1.HoleCount;
            var usP2Holes = Poly2.HoleCount;

            // *** Rim Rim Intersections
            Poly1.Rim.Lines.GetIntersections(Poly2.Rim.Lines,
                                             IntPointsTemp, IndexesRim1, IndexesRim2,
                                             Poly1.Rim.BoundingRect, Poly2.Rim.BoundingRect);

            IntPointsRim1.AddCopy(IntPointsTemp);
            IntPointsRim2.ExtractAllOf(IntPointsTemp);

            // *** Rim Hole Intersections
            for (var i = 0; i < usP2Holes; i++)
            {
                Debug.Assert(IntPointsTemp.Count == 0);

                IntPoints2AllHoles.Add(new C2DPointSet());
                Indexes2AllHoles.Add(new List <int>());

                if (Poly1.Rim.BoundingRect.Overlaps(Poly2.GetHole(i).BoundingRect))
                {
                    Poly1.Rim.Lines.GetIntersections(Poly2.GetHole(i).Lines,
                                                     IntPointsTemp, IndexesRim1, Indexes2AllHoles[i],
                                                     Poly1.Rim.BoundingRect, Poly2.GetHole(i).BoundingRect);

                    IntPointsRim1.AddCopy(IntPointsTemp);
                    IntPoints2AllHoles[i].ExtractAllOf(IntPointsTemp);
                }
            }
            // *** Rim Hole Intersections
            for (var j = 0; j < usP1Holes; j++)
            {
                Debug.Assert(IntPointsTemp.Count == 0);

                IntPoints1AllHoles.Add(new C2DPointSet());
                Indexes1AllHoles.Add(new List <int>());

                if (Poly2.Rim.BoundingRect.Overlaps(Poly1.GetHole(j).BoundingRect))
                {
                    Poly2.Rim.Lines.GetIntersections(Poly1.GetHole(j).Lines,
                                                     IntPointsTemp, IndexesRim2, Indexes1AllHoles[j],
                                                     Poly2.Rim.BoundingRect, Poly1.GetHole(j).BoundingRect);

                    IntPointsRim2.AddCopy(IntPointsTemp);
                    IntPoints1AllHoles[j].ExtractAllOf(IntPointsTemp);
                }
            }

            // *** Quick Escape
            bool bRim1StartInPoly2 = Poly2.Contains(Poly1.Rim.Lines[0].GetPointFrom());
            bool bRim2StartInPoly1 = Poly1.Contains(Poly2.Rim.Lines[0].GetPointFrom());

            if (IntPointsRim1.Count != 0 || IntPointsRim2.Count != 0 ||
                bRim1StartInPoly2 || bRim2StartInPoly1)
            // pos no interaction
            {
                // *** Rim Routes
                Poly1.Rim.GetRoutes(IntPointsRim1, IndexesRim1, Routes1,
                                    bRim1StartInPoly2, bP1RoutesInside);
                Poly2.Rim.GetRoutes(IntPointsRim2, IndexesRim2, Routes2,
                                    bRim2StartInPoly1, bP2RoutesInside);

                if (IntPointsRim1.Count % 2 != 0)               // Must be even
                {
                    grid.LogDegenerateError();
                    //  Debug.Assert(false);
                }

                if (IntPointsRim2.Count % 2 != 0)               // Must be even
                {
                    grid.LogDegenerateError();
                    //   Debug.Assert(false);
                }

                // *** Hole Hole Intersections
                for (var h = 0; h < usP1Holes; h++)
                {
                    for (var k = 0; k < usP2Holes; k++)
                    {
                        Debug.Assert(IntPointsTemp.Count == 0);
                        var pHole1 = Poly1.GetHole(h);
                        var pHole2 = Poly2.GetHole(k);

                        if (pHole1.BoundingRect.Overlaps(pHole2.BoundingRect))
                        {
                            pHole1.Lines.GetIntersections(pHole2.Lines,
                                                          IntPointsTemp, Indexes1AllHoles[h], Indexes2AllHoles[k],
                                                          pHole1.BoundingRect, pHole2.BoundingRect);

                            IntPoints1AllHoles[h].AddCopy(IntPointsTemp);
                            IntPoints2AllHoles[k].ExtractAllOf(IntPointsTemp);
                        }
                    }
                }


                // *** Hole Routes
                for (var a = 0; a < usP1Holes; a++)
                {
                    var pHole = Poly1.GetHole(a);

                    if (IntPoints1AllHoles[a].Count % 2 != 0)                   // Must be even
                    {
                        grid.LogDegenerateError();
                        //   Debug.Assert(false);
                    }

                    if (pHole.Lines.Count != 0)
                    {
                        bool bHole1StartInside = Poly2.Contains(pHole.Lines[0].GetPointFrom());
                        if (IntPoints1AllHoles[a].Count == 0)
                        {
                            if (bHole1StartInside == bP1RoutesInside)
                            {
                                CompleteHoles1.Add(new C2DPolyBase(pHole));
                            }
                        }
                        else
                        {
                            pHole.GetRoutes(IntPoints1AllHoles[a], Indexes1AllHoles[a], Routes1,
                                            bHole1StartInside, bP1RoutesInside);
                        }
                    }
                }
                // *** Hole Routes
                for (var b = 0; b < usP2Holes; b++)
                {
                    var pHole = Poly2.GetHole(b);

                    if (IntPoints2AllHoles[b].Count % 2 != 0)                   // Must be even
                    {
                        grid.LogDegenerateError();
                        //    Debug.Assert(false);
                    }

                    if (pHole.Lines.Count != 0)
                    {
                        bool bHole2StartInside = Poly1.Contains(pHole.Lines[0].GetPointFrom());
                        if (IntPoints2AllHoles[b].Count == 0)
                        {
                            if (bHole2StartInside == bP2RoutesInside)
                            {
                                CompleteHoles2.Add(new C2DPolyBase(pHole));
                            }
                        }
                        else
                        {
                            pHole.GetRoutes(IntPoints2AllHoles[b], Indexes2AllHoles[b], Routes2,
                                            bHole2StartInside, bP2RoutesInside);
                        }
                    }
                }
            }


            //for (unsigned int i = 0 ; i < IntPoints1AllHoles.size(); i++)
            //    delete IntPoints1AllHoles[i];
            //for (unsigned int i = 0 ; i < IntPoints2AllHoles.size(); i++)
            //    delete IntPoints2AllHoles[i];
            //for (unsigned int i = 0 ; i < Indexes1AllHoles.size(); i++)
            //    delete Indexes1AllHoles[i];
            //for (unsigned int i = 0 ; i < Indexes2AllHoles.size(); i++)
            //    delete Indexes2AllHoles[i];
        }
Пример #8
0
        /// <summary>
        /// Returns the boolean result (e.g. union) of 2 shapes. Boolean Operation defined by
        /// the inside / outside flags.
        /// </summary>
        /// <param name="Other">Other polygon.</param>
        /// <param name="HoledPolys">Set of polygons to recieve the result.</param>
        /// <param name="bThisInside">Does the operation require elements of this INSIDE the other.</param>
        /// <param name="bOtherInside">Does the operation require elements of the other INSIDE this.</param>
        /// <param name="grid">The grid with the degenerate settings.</param>
        public void GetBoolean(C2DHoledPolyBase Other, List <C2DHoledPolyBase> HoledPolys,
                               bool bThisInside, bool bOtherInside,
                               CGrid grid)
        {
            if (_Rim.Lines.Count == 0 || Other.Rim.Lines.Count == 0)
            {
                return;
            }

            if (_Rim.BoundingRect.Overlaps(Other.Rim.BoundingRect))
            {
                switch (grid.DegenerateHandling)
                {
                case CGrid.eDegenerateHandling.None:
                {
                    var CompleteHoles1 = new List <C2DPolyBase>();
                    var CompleteHoles2 = new List <C2DPolyBase>();
                    var Routes1        = new C2DLineBaseSetSet();
                    var Routes2        = new C2DLineBaseSetSet();
                    GetRoutes(this, bThisInside, Other, bOtherInside, Routes1, Routes2,
                              CompleteHoles1, CompleteHoles2, grid);

                    Routes1.ExtractAllOf(Routes2);

                    if (Routes1.Count > 0)
                    {
                        Routes1.MergeJoining();

                        var Polygons = new List <C2DPolyBase>();

                        for (var i = Routes1.Count - 1; i >= 0; i--)
                        {
                            C2DLineBaseSet pRoute = Routes1[i];
                            if (pRoute.IsClosed(true))
                            {
                                Polygons.Add(new C2DPolyBase());
                                Polygons[Polygons.Count - 1].CreateDirect(pRoute);
                            }
                            else
                            {
                                //   Debug.Assert(false);
                                grid.LogDegenerateError();
                            }
                        }

                        var NewComPolys = new C2DHoledPolyBaseSet();

                        PolygonsToHoledPolygons(NewComPolys, Polygons);

                        NewComPolys.AddKnownHoles(CompleteHoles1);

                        NewComPolys.AddKnownHoles(CompleteHoles2);

                        if (!bThisInside && !bOtherInside && NewComPolys.Count != 1)
                        {
                            //  Debug.Assert(false);
                            grid.LogDegenerateError();
                        }


                        HoledPolys.AddRange(NewComPolys);

                        NewComPolys.Clear();
                    }
                }
                break;

                case CGrid.eDegenerateHandling.RandomPerturbation:
                {
                    var OtherCopy = new C2DHoledPolyBase(Other);
                    OtherCopy.RandomPerturb();
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(OtherCopy, HoledPolys, bThisInside, bOtherInside, grid);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.RandomPerturbation;
                }
                break;

                case CGrid.eDegenerateHandling.DynamicGrid:
                {
                    var Rect = new C2DRect();
                    if (_Rim.BoundingRect.Overlaps(Other.Rim.BoundingRect, Rect))
                    {
                        //double dOldGrid = CGrid::GetGridSize();
                        grid.SetToMinGridSize(Rect, false);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                        GetBoolean(Other, HoledPolys, bThisInside, bOtherInside, grid);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.DynamicGrid;
                    }
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGrid:
                {
                    var P1 = new C2DHoledPolyBase(this);
                    var P2 = new C2DHoledPolyBase(Other);
                    P1.SnapToGrid(grid);
                    P2.SnapToGrid(grid);
                    var V1            = new C2DVector(P1.Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;                     // ensure it snaps back to original grid positions.
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;          // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.

                    P2.Move(V1);
                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    P1.GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
                }
                break;

                case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:
                {
                    var P2            = new C2DHoledPolyBase(Other);
                    var V1            = new C2DVector(_Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
                    var dPerturbation = grid.GridSize;
                    if (V1.i > 0)
                    {
                        V1.i = dPerturbation;
                    }
                    else
                    {
                        V1.i = -dPerturbation;     // move away slightly if possible
                    }
                    if (V1.j > 0)
                    {
                        V1.j = dPerturbation;
                    }
                    else
                    {
                        V1.j = -dPerturbation;     // move away slightly if possible
                    }
                    V1.i *= 0.411923;              // ensure it snaps back to original grid positions.
                    V1.j *= 0.313131;              // ensure it snaps back to original grid positions.
                    P2.Move(V1);

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                    GetBoolean(P2, HoledPolys, bThisInside, bOtherInside, grid);

                    for (var i = 0; i < HoledPolys.Count; i++)
                    {
                        HoledPolys[i].SnapToGrid(grid);
                    }

                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
                }
                break;
                }        // switch
            }
        }