/// <summary> /// Constructor. /// </summary> /// <param name="Other">Other polygon to set this to.</param> public C2DHoledPolyArc(C2DHoledPolyBase Other) { _Rim = new C2DPolyArc(Other.Rim); for (int i = 0; i < Other.HoleCount; i++) { _Holes.Add(new C2DPolyArc(Other.GetHole(i))); } }
/// <summary> /// Constructor. /// </summary> public C2DHoledPolygon(C2DHoledPolyBase Other) { _Rim = new C2DPolygon(Other.Rim); for (int i = 0; i < Other.HoleCount; i++) { _Holes.Add(new C2DPolygon(Other.GetHole(i) )); } }
/// <summary> /// Assignment. /// </summary> /// <param name="Other">Other polygon to set this to.</param> public new void Set(C2DHoledPolyBase Other) { _Rim.Set(Other.Rim); _Holes.Clear(); for (int i = 0; i < Other.HoleCount; i++) { _Holes.Add(new C2DPolyArc(Other.GetHole(i))); } }
/// <summary> /// Assignment. /// </summary> /// <param name="Other">Other polygon to set this to.</param> public void Set(C2DHoledPolyBase Other) { _Rim.Set(Other.Rim); _Holes.Clear(); for (int i = 0 ; i < Other.HoleCount; i++) { _Holes.Add(new C2DPolyBase(Other.GetHole(i))); } }
/// <summary> /// Assignment. /// </summary> /// <param name="Other">Other polygon to set this to.</param> public new void Set(C2DHoledPolyBase Other) { _Holes.Clear(); _Rim = new C2DPolygon(Other.Rim); for (var i = 0; i < Other.HoleCount; i++) { _Holes.Add(new C2DPolygon(Other.GetHole(i))); } }
/// <summary> /// Draws a polygon /// </summary> public void Draw(C2DHoledPolyBase Poly, Graphics graphics, Pen pen) { Draw(Poly.Rim, graphics, pen); for (int h = 0; h < Poly.HoleCount; h++) { Draw(Poly.GetHole(h), graphics, pen); } }
/// <summary> /// Draws a polygon filled. /// </summary> public void DrawFilled(C2DHoledPolyBase Poly, Graphics graphics, Brush brush) { if (Poly.Rim.Lines.Count == 0) { return; } System.Drawing.Drawing2D.GraphicsPath gp = CreatePath(Poly.Rim); for (int h = 0; h < Poly.HoleCount; h++) { if (Poly.GetHole(h).Lines.Count > 2) { gp.AddPath(CreatePath(Poly.GetHole(h)), false); } } gp.FillMode = System.Drawing.Drawing2D.FillMode.Alternate; graphics.FillPath(brush, gp); }
/// <summary> /// True if this overlaps the other. /// </summary> /// <param name="Other">Other polygon to test for.</param> public bool Overlaps(C2DHoledPolyBase Other) { if (!Overlaps(Other.Rim)) { return(false); } for (var i = 0; i < Other.HoleCount; i++) { if (Other.GetHole(i).Contains(_Rim)) { return(false); } } return(true); }
/// <summary> /// Polygon entirely inside test. /// </summary> /// <param name="Polygon">Polygon to test for.</param> public bool Contains(C2DHoledPolyBase Polygon) { if (!Contains(Polygon.Rim)) { return(false); } for (var i = 0; i < Polygon.HoleCount; i++) { if (!Contains(Polygon.GetHole(i))) { return(false); } } return(true); }
/// <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]; }
/// <summary> /// True if this overlaps the other. /// </summary> /// <param name="Other">Other polygon to test for.</param> public bool Overlaps(C2DHoledPolyBase Other) { if (!Overlaps( Other.Rim )) return false; for (int i = 0 ; i < Other.HoleCount; i++) { if (Other.GetHole(i).Contains(_Rim)) return false; } return true; }
/// <summary> /// Polygon entirely inside test. /// </summary> /// <param name="Polygon">Polygon to test for.</param> public bool Contains(C2DHoledPolyBase Polygon) { if (! Contains( Polygon.Rim)) return false; for (int i = 0 ; i < Polygon.HoleCount; i++) { if (! Contains( Polygon.GetHole(i)) ) return false; } return true; }
/// <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]; }
/// <summary> /// Draws a polygon filled. /// </summary> public void DrawFilled(C2DHoledPolyBase Poly, Graphics graphics, Brush brush) { if (Poly.Rim.Lines.Count == 0) return; System.Drawing.Drawing2D.GraphicsPath gp = CreatePath(Poly.Rim); for (int h = 0; h < Poly.HoleCount; h++) { if (Poly.GetHole(h).Lines.Count > 2) { gp.AddPath( CreatePath( Poly.GetHole(h)), false); } } gp.FillMode = System.Drawing.Drawing2D.FillMode.Alternate; graphics.FillPath(brush, gp); }