/// <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:
			        {
				        List<C2DPolyBase> CompleteHoles1 = new List<C2DPolyBase>();
				        List<C2DPolyBase> CompleteHoles2 = new List<C2DPolyBase>();
				        C2DLineBaseSetSet Routes1 = new C2DLineBaseSetSet(); 
				        C2DLineBaseSetSet Routes2 = new C2DLineBaseSetSet(); 
				        GetRoutes( this, bThisInside, Other, bOtherInside, Routes1, Routes2,
								        CompleteHoles1, CompleteHoles2, grid);

				        Routes1.ExtractAllOf(Routes2);

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

					        List<C2DPolyBase> Polygons = new List<C2DPolyBase>();

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

                            C2DHoledPolyBaseSet 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:
			        {
				        C2DHoledPolyBase 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:
			        {
				        C2DRect 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:
			        {
				        C2DHoledPolyBase P1 = new C2DHoledPolyBase(this);
                        C2DHoledPolyBase P2 = new C2DHoledPolyBase(Other);
				        P1.SnapToGrid(grid);
				        P2.SnapToGrid(grid);
				        C2DVector V1 = new C2DVector( P1.Rim.BoundingRect.TopLeft,  P2.Rim.BoundingRect.TopLeft);
				        double 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 (int i = 0 ; i < HoledPolys.Count ; i++)
				            HoledPolys[i].SnapToGrid(grid);

                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;

			        }
			        break;
		        case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:
			        {
				        C2DHoledPolyBase P2 = new C2DHoledPolyBase(Other);
                        C2DVector V1 = new C2DVector(_Rim.BoundingRect.TopLeft, P2.Rim.BoundingRect.TopLeft);
				        double 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 (int i = 0; i < HoledPolys.Count; i++)
                            HoledPolys[i].SnapToGrid(grid);

                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
			        }
			        break;
		        }// switch
	        }
        }
Esempio n. 2
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:
			        {
				        C2DLineBaseSetSet Routes1 = new C2DLineBaseSetSet();
                        C2DLineBaseSetSet 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.
					        List<C2DPolyBase> Polygons = new List<C2DPolyBase>();
					        // Turn the routes into polygons.
					        for (int 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
					        C2DHoledPolyBaseSet 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 (int i = 0; i < Polygons.Count; i++)
						            HoledPolys.Add(new C2DHoledPolyBase(Polygons[i]));
					        }

					        // Now add them all to the provided set.
                            for (int i = 0 ; i < NewComPolys.Count; i++)
					            HoledPolys.Add(NewComPolys[i]);
				        }
			        }
			        break;
		        case CGrid.eDegenerateHandling.RandomPerturbation:
			        {
				        C2DPolyBase 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:
			        {
				        C2DRect Rect = new C2DRect(); 
				        if (this.BoundingRect.Overlaps(Other.BoundingRect, Rect))
				        {
					        double 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:
			        {
				        C2DPolyBase P1 = new C2DPolyBase(this);
                        C2DPolyBase P2 = new C2DPolyBase(Other);
				        P1.SnapToGrid(grid);
                        P2.SnapToGrid(grid);
				        C2DVector V1 = new C2DVector( P1.BoundingRect.TopLeft,  P2.BoundingRect.TopLeft);
				        double 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 (int i = 0; i < HoledPolys.Count; i++)
                            HoledPolys[i].SnapToGrid(grid);

	                    grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGrid;
			        }
			        break;
		        case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:
			        {
				        C2DPolyBase P2 = new C2DPolyBase(Other);
				        C2DVector V1 = new C2DVector( this.BoundingRect.TopLeft,  P2.BoundingRect.TopLeft);
				        double 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 (int i = 0; i < HoledPolys.Count; i++)
                            HoledPolys[i].SnapToGrid(grid);
                        grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
			        }
			        break;
		        }
                       
            }
        }