Пример #1
0
 /// <summary>
 /// Snaps this to the conceptual grid.
 /// </summary>
 public abstract void SnapToGrid(CGrid grid);
Пример #2
0
 /// <summary>
 /// Snaps this to the conceptual grid.
 /// </summary>
 /// <param name="grid">Grid to snap to.</param> 
 public override void SnapToGrid(CGrid grid)
 {
     P1.SnapToGrid(grid);
     P2.SnapToGrid(grid);
     P3.SnapToGrid(grid);
 }
        /// <summary>
        /// Gets the union of the 2 shapes.
        /// </summary>
        /// <param name="Other">The other shape.</param> 
        /// <param name="Polygons">The set to recieve the result.</param> 
        /// <param name="grid">The degenerate settings.</param> 
        public void GetUnion(C2DHoledPolygon Other, List<C2DHoledPolygon> Polygons,
                                            CGrid grid)
        {
            List<C2DHoledPolyBase> NewPolys = new List<C2DHoledPolyBase>();

            base.GetUnion(Other, NewPolys, grid);

            for (int i = 0; i < NewPolys.Count; i++)
                Polygons.Add(new C2DHoledPolygon(NewPolys[i]));
        }
Пример #4
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:
			        {
				        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
	        }
        }
Пример #5
0
 /// <summary>
 /// Snaps this to the conceptual grid.
 /// </summary>
 /// <param name="grid">Grid to snap to.</param>
 public override void SnapToGrid(CGrid grid)
 {
     TopLeft.SnapToGrid(grid);
     BottomRight.SnapToGrid(grid);
 }
Пример #6
0
        /// <summary>
        /// Returns the difference between this and the other polygon.
        /// </summary>
        /// <param name="Other">Other polygon.</param> 
        /// <param name="HoledPolys">Set to receieve all the resulting polygons.</param> 
        /// <param name="grid">Grid containing the degenerate handling settings.</param> 
        public void GetNonOverlaps(C2DHoledPolyBase Other, List<C2DHoledPolyBase> HoledPolys, 
							    CGrid grid) 
        {
        	GetBoolean(Other, HoledPolys, false, true, grid);

        }
Пример #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;
		    }

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


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

		    int usP1Holes = Poly1.HoleCount;
		    int 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 ( int 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 ( int 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 (int h = 0 ; h < usP1Holes; h++)
			    {
				    for ( int k = 0 ; k < usP2Holes; k++)
				    {
					    Debug.Assert(IntPointsTemp.Count == 0);	
					    C2DPolyBase pHole1 = Poly1.GetHole(h);
                        C2DPolyBase 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 (int a = 0 ; a < usP1Holes; a++)
			    {
				    C2DPolyBase 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 (int b = 0 ; b < usP2Holes; b++)
			    {
				    C2DPolyBase 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>
 /// Snaps this to the conceptual grid.
 /// </summary>
 public abstract void SnapToGrid(CGrid grid);
Пример #9
0
        /// <summary>
        /// Unification by growing shapes of fairly equal size (fastest for large groups).
        /// </summary>
        /// <param name="grid">The CGrid with the degenerate settings.</param>
        public void UnifyProgressive(CGrid grid)
        {
            // Record the degenerate handling so we can reset.
            CGrid.eDegenerateHandling DegenerateHandling = grid.DegenerateHandling;
            switch (grid.DegenerateHandling)
            {
            case CGrid.eDegenerateHandling.RandomPerturbation:
                for (var i = 0; i < Count; i++)
                {
                    this[i].RandomPerturb();
                }
                grid.DegenerateHandling = CGrid.eDegenerateHandling.None;
                break;

            case CGrid.eDegenerateHandling.DynamicGrid:

                break;

            case CGrid.eDegenerateHandling.PreDefinedGrid:
                for (var i = 0; i < Count; i++)
                {
                    this[i].SnapToGrid(grid);
                }
                grid.DegenerateHandling = CGrid.eDegenerateHandling.PreDefinedGridPreSnapped;
                break;

            case CGrid.eDegenerateHandling.PreDefinedGridPreSnapped:

                break;
            }


            var NoUnionSet   = new C2DHoledPolyBaseSet();
            var PossUnionSet = new C2DHoledPolyBaseSet();
            var SizeHoldSet  = new C2DHoledPolyBaseSet();
            var UnionSet     = new C2DHoledPolyBaseSet();
            var TempSet      = new C2DHoledPolyBaseSet();

            var nThreshold = GetMinLineCount();

            if (nThreshold == 0)
            {
                nThreshold = 10;                // avoid infinate loop.
            }
            // Assumed all are size held to start
            SizeHoldSet.AddRange(this);
            this.Clear();

            do
            {
                // double the threshold
                nThreshold *= 3;

                // Put all the possible intersects back in this.
                this.AddRange(PossUnionSet);
                PossUnionSet.Clear();

                // Put all the size held that are small enough back (or in to start with)
                while (SizeHoldSet.Count > 0)
                {
                    var pLast = SizeHoldSet[SizeHoldSet.Count - 1];
                    SizeHoldSet.RemoveAt(SizeHoldSet.Count - 1);

                    if (pLast.GetLineCount() > nThreshold)
                    {
                        TempSet.Add(pLast);
                    }
                    else
                    {
                        this.Add(pLast);
                    }
                }
                SizeHoldSet.AddRange(TempSet);
                TempSet.Clear();


                // Cycle through all popping the last and finding a union
                while (Count > 0)
                {
                    var pLast = this[Count - 1];
                    this.RemoveAt(Count - 1);

                    var bIntersect = false;

                    var i = 0;
                    while (i < Count && !bIntersect)
                    {
                        this[i].GetUnion(pLast, UnionSet, grid);

                        if (UnionSet.Count == 1)
                        {
                            var pUnion = UnionSet[UnionSet.Count - 1];
                            UnionSet.RemoveAt(UnionSet.Count - 1);

                            if (pUnion.GetLineCount() > nThreshold)
                            {
                                RemoveAt(i);
                                SizeHoldSet.Add(pUnion);
                            }
                            else
                            {
                                this[i] = pUnion;
                                i++;
                            }

                            bIntersect = true;
                        }
                        else
                        {
                            if (UnionSet.Count != 0)
                            {
                                grid.LogDegenerateError();
                            }
                            UnionSet.Clear();
                            i++;
                        }
                    }

                    if (!bIntersect)
                    {
                        var bPosInterSect = false;
                        for (var j = 0; j < SizeHoldSet.Count; j++)
                        {
                            if (pLast.Rim.BoundingRect.Overlaps(
                                    SizeHoldSet[j].Rim.BoundingRect))
                            {
                                bPosInterSect = true;
                                break;
                            }
                        }

                        if (bPosInterSect)
                        {
                            PossUnionSet.Add(pLast);
                        }
                        else
                        {
                            NoUnionSet.Add(pLast);
                        }
                    }
                }
            }while (SizeHoldSet.Count != 0);


            this.AddRange(NoUnionSet);
            NoUnionSet.Clear();

            grid.DegenerateHandling = DegenerateHandling;
        }
Пример #10
0
 /// <summary>
 /// Returns the difference between this and the other polygon.
 /// </summary>
 /// <param name="Other">Other polygon.</param>
 /// <param name="HoledPolys">Set to receieve all the resulting polygons.</param>
 /// <param name="grid">Grid containing the degenerate handling settings.</param>
 public void GetNonOverlaps(C2DHoledPolyBase Other, List <C2DHoledPolyBase> HoledPolys,
                            CGrid grid)
 {
     GetBoolean(Other, HoledPolys, false, true, grid);
 }
Пример #11
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];
        }
Пример #12
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
            }
        }
Пример #13
0
        /// <summary>
        /// Snaps to the conceptual grid
        /// </summary>
        /// <param name="grid">The grid.</param> 
        public override void SnapToGrid(CGrid grid)
        {
            _Centre.SnapToGrid(grid);

            double dMultiple = Math.Abs(Radius / grid.GridSize) + 0.5;

            dMultiple = Math.Floor(dMultiple);

            if (Radius < 0)
                Radius = -dMultiple * grid.GridSize;
            else
                Radius = dMultiple * grid.GridSize;
        }
Пример #14
0
    void merge(C2DHoledPolyArc stoneShape, List<C2DHoledPolyArc> shapesToMerge, List<C2DHoledPolyArc> ownShape)
    {
        List<C2DHoledPolyArc> acc = new List<C2DHoledPolyArc>();
        CGrid grid = new CGrid ();
        grid.SetGridSize(0.01f);

        if (shapesToMerge.Count == 0) {
            ownShape.Add(stoneShape);
            return;
        }

        foreach (C2DHoledPolyArc shape in shapesToMerge) {
            ownShape.Remove(shape);
        }

        foreach (C2DHoledPolyArc shape in shapesToMerge) {
            shape.GetUnion(stoneShape, acc, grid);
        }

        ownShape.Add(acc[acc.Count-1]);
    }
Пример #15
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;
		        }
                       
            }
        }
Пример #16
0
        /// <summary>
        /// Snaps this to the conceptual grid.
        /// </summary>
        /// <param name="grid">Grid to snap to.</param> 
        public override void SnapToGrid(CGrid grid)
        {
            TopLeft.SnapToGrid(grid);
            BottomRight.SnapToGrid(grid);

        }
Пример #17
0
 /// <summary>
 /// Snaps this to the conceptual grid.
 /// </summary>
 /// <param name="grid">The grid.</param>
 public override void SnapToGrid(CGrid grid)
 {
     Arc.SnapToGrid(grid);
 }
Пример #18
0
 /// <summary>
 /// Snaps this to the conceptual grid.
 /// </summary>
 /// <param name="grid">Grid to snap to.</param>
 public override void SnapToGrid(CGrid grid)
 {
     P1.SnapToGrid(grid);
     P2.SnapToGrid(grid);
     P3.SnapToGrid(grid);
 }
Пример #19
0
        /// <summary>
        /// Returns the union of this and the other.
        /// </summary>
        /// <param name="Other">Other polygon.</param> 
        /// <param name="HoledPolys">Set to receieve all the resulting polygons.</param> 
        /// <param name="grid">Grid containing the degenerate handling settings.</param> 
        public void GetUnion(C2DHoledPolyBase Other, List<C2DHoledPolyBase> HoledPolys,
						    CGrid grid) 
        {
        	GetBoolean(Other, HoledPolys,false , false, grid);
        }
Пример #20
0
 /// <summary>
 /// Returns the union of this with another.
 /// </summary>
 /// <param name="Other">The other polygon.</param>
 /// <param name="Polygons">The output polygons.</param>
 /// <param name="grid">The degenerate settings.</param>
 public void GetUnion(C2DPolyBase Other, List <C2DHoledPolyBase> Polygons,
                      CGrid grid)
 {
     GetBoolean(Other, Polygons, false, false, grid);
 }
Пример #21
0
        /// <summary>
        /// Snaps this to the conceptual grip.
        /// </summary>
        /// <param name="grid">The grid to snap to.</param> 
        public void SnapToGrid(CGrid grid)
        {
            _Rim.SnapToGrid(grid);

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        GetHole(i).SnapToGrid(grid);
	        }
        }
Пример #22
0
 /// <summary>
 /// Returns the overlaps of this with another.
 /// </summary>
 /// <param name="Other">The other polygon.</param>
 /// <param name="Polygons">The output polygons.</param>
 /// <param name="grid">The degenerate settings.</param>
 public void GetOverlaps(C2DPolyBase Other, List <C2DHoledPolyBase> Polygons,
                         CGrid grid)
 {
     GetBoolean(Other, Polygons, true, true, grid);
 }
Пример #23
0
        /// <summary>
        /// Snaps this to the grid. The x and y values can only be multiples or the grid size.
        /// </summary>
        /// <param name="grid">The grid to snap this to.</param>
        public override void SnapToGrid(CGrid grid)
        {
            double dxMultiple = Math.Abs(x / grid.GridSize) + 0.5;

            dxMultiple = Math.Floor(dxMultiple);

            if (x < 0)
                x = -dxMultiple * grid.GridSize;
            else
                x = dxMultiple * grid.GridSize;

            double dyMultiple = Math.Abs(y / grid.GridSize) + 0.5;

            dyMultiple = Math.Floor(dyMultiple);

            if (y < 0)
                y = -dyMultiple * grid.GridSize;
            else
                y = dyMultiple * grid.GridSize;
        }
Пример #24
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;
                }
            }
        }
Пример #25
0
 /// <summary>
 /// Snaps this to the conceptual grid.
 /// </summary>
 /// <param name="grid">The grid.</param>
 public override void SnapToGrid(CGrid grid)
 {
     Arc.SnapToGrid(grid);
 }
Пример #26
0
 /// <summary>
 /// Snap to the conceptual grid.
 /// </summary>
 /// <param name="grid">The grid.</param>
 public override void SnapToGrid(CGrid grid)
 {
     for (int i = 0; i < _Lines.Count; i++)
     {
         _Lines[i].SnapToGrid(grid);
     }
     for(int i = 0; i < _LineRects.Count; i++)
     {
         _LineRects[i].SnapToGrid(grid);
     }
     BoundingRect.SnapToGrid(grid);
 }
Пример #27
0
        /// <summary>
        /// Gets the overlaps of the 2 shapes.	
        /// </summary>
        /// <param name="Other">The other shape.</param> 
        /// <param name="Polygons">The set to recieve the result.</param> 
        /// <param name="grid">The degenerate settings.</param> 
        public void GetOverlaps(C2DPolyArc Other, List<C2DHoledPolyArc> Polygons,
										    CGrid grid)
        {
            List<C2DHoledPolyBase> NewPolys = new List<C2DHoledPolyBase>();

            base.GetOverlaps(Other, NewPolys, grid);

            for (int i = 0; i < NewPolys.Count; i++)
                Polygons.Add(new C2DHoledPolyArc(NewPolys[i]));
        }
Пример #28
0
        /// <summary>
        /// Returns the overlaps of this with another.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        /// <param name="Polygons">The output polygons.</param>
        /// <param name="grid">The degenerate settings.</param>
        public void GetOverlaps(C2DPolyBase Other, List<C2DHoledPolyBase> Polygons,
										    CGrid grid)
        {
            GetBoolean(Other, Polygons, true, true, grid);
        }
Пример #29
0
        /// <summary>
        /// Snaps this to the conceptual grid.
        /// </summary>
        /// <param name="grid">The grid to snap to.</param>
        public override void SnapToGrid(CGrid grid)
        {
            C2DPoint pt = GetPointTo();

            pt.SnapToGrid(grid);

            point.SnapToGrid(grid);
            SetPointTo(pt);
        }
Пример #30
0
        /// <summary>
        /// Snaps this to the conceptual grid.
        /// </summary>
        /// <param name="grid">The grid object to snap this to.</param> 
        public override void SnapToGrid(CGrid grid)
        {
            Line.SnapToGrid(grid);

            double dLength = Line.vector.GetLength();

            if (dLength > (2 * Radius))
            {
                Radius = dLength / 1.999999999999;	// To ensure errors in the right way.
            }
        }