/// <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);
        }
Beispiel #2
0
        /// <summary>
        /// Adds a set of holes to the current set of polygons as holes within them.
        /// </summary>
        /// <param name="pOther">The polygon set to add as holes.</param>
        public void AddKnownHoles(List <C2DPolyBase> pOther)
        {
            if (Count != 0)
            {
                while (pOther.Count > 0)
                {
                    C2DPolyBase pLast = pOther[pOther.Count - 1];
                    pOther.RemoveAt(pOther.Count - 1);
                    if (pLast.Lines.Count > 0)
                    {
                        int  i      = Count - 1;
                        bool bFound = false;
                        while (i > 0 && !bFound)
                        {
                            if (this[i].Contains(pLast.Lines[0].GetPointFrom()))
                            {
                                this[i].AddHole(pLast);
                                bFound = true;
                            }
                            i--;
                        }

                        if (!bFound)
                        {
                            this[0].AddHole(pLast);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="Other">Other polygon to set this to.</param>
        public C2DHoledPolyBase(C2DHoledPolyBase Other)
        {
            _Rim = new C2DPolyBase(Other.Rim);

            for (var i = 0; i < Other.HoleCount; i++)
            {
                _Holes.Add(new C2DPolyBase(Other.GetHole(i)));
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="Other">Other polygon to set this to.</param> 
	    public C2DHoledPolyBase(C2DHoledPolyBase Other)
        {
	        _Rim =  new C2DPolyBase( Other.Rim);

	        for (int i = 0 ; i < Other.HoleCount; i++)
	        {
		        _Holes.Add(new C2DPolyBase(Other.GetHole(i)));
	        }
        }
Beispiel #5
0
        /// <summary>
        /// Distance from the polygon provided.
        /// </summary>
        /// <param name="Poly">Polygon to find the distance to.</param>
        /// <param name="ptOnThis">Closest point on this to recieve the result.</param>
        /// <param name="ptOnOther">Closest point on the other to recieve the result.</param>
        public double Distance(C2DPolyBase Poly, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            var ptOnThisResult  = new C2DPoint();
            var ptOnOtherResult = new C2DPoint();


            var dResult = _Rim.Distance(Poly, ptOnThis, ptOnOther);

            if (dResult == 0)
            {
                return(0);
            }

            ptOnThisResult.Set(ptOnThis);
            ptOnOtherResult.Set(ptOnOther);

            var bInside = dResult < 0;

            dResult = Math.Abs(dResult);

            for (var i = 0; i < _Holes.Count; i++)
            {
                var dDist = _Holes[i].Distance(Poly, ptOnThis, ptOnOther);
                if (dDist == 0)
                {
                    return(0);
                }


                if (dDist < 0)
                {
                    bInside = false;
                }
                if (Math.Abs(dDist) < dResult)
                {
                    ptOnThisResult.Set(ptOnThis);
                    ptOnOtherResult.Set(ptOnOther);

                    dResult = Math.Abs(dDist);
                }
            }

            ptOnThis.Set(ptOnThisResult);
            ptOnOther.Set(ptOnOtherResult);

            if (bInside)
            {
                return(dResult);
            }
            else
            {
                return(-dResult);
            }
        }
Beispiel #6
0
 /// <summary>
 /// Hole assignment.
 /// </summary>
 public new void SetHole(int i, C2DPolyBase Poly)
 {
     if (Poly is C2DPolyArc)
     {
         _Holes[i] = Poly;
     }
     else
     {
         Debug.Assert(false, "Invalid Hole type");
     }
 }
Beispiel #7
0
 /// <summary>
 /// Hole addition.
 /// </summary>
 public new void AddHole(C2DPolyBase Poly)
 {
     if (Poly is C2DPolyArc)
     {
         _Holes.Add(Poly);
     }
     else
     {
         Debug.Assert(false, "Invalid Hole type");
     }
 }
Beispiel #8
0
        /// <summary>
        /// Creates a path based on a polygon.
        /// </summary>
        private System.Drawing.Drawing2D.GraphicsPath CreatePath(C2DPolyBase Poly)
        {
            System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();


            if (Poly.Lines.Count == 0)
            {
                return(gp);
            }

            for (int i = 0; i < Poly.Lines.Count; i++)
            {
                if (Poly.Lines[i] is C2DLine)
                {
                    C2DPoint ptFrom = Poly.Lines[i].GetPointFrom();
                    C2DPoint ptTo   = Poly.Lines[i].GetPointTo();
                    ScaleAndOffSet(ptFrom);
                    ScaleAndOffSet(ptTo);
                    gp.AddLine((int)ptFrom.x, (int)ptFrom.y, (int)ptTo.x, (int)ptTo.y);
                }
                else if (Poly.Lines[i] is C2DArc)
                {
                    C2DRect Rect        = new C2DRect();
                    int     nStartAngle = 0;
                    int     nSweepAngle = 0;

                    GetArcParameters(Poly.Lines[i] as C2DArc, Rect, ref nStartAngle, ref nSweepAngle);

                    if (nSweepAngle == 0)
                    {
                        nSweepAngle = 1;
                    }

                    int Width = (int)Rect.Width();
                    if (Width == 0)
                    {
                        Width = 1;
                    }
                    int Height = (int)Rect.Height();
                    if (Height == 0)
                    {
                        Height = 1;
                    }

                    gp.AddArc((int)Rect.TopLeft.x, (int)Rect.BottomRight.y,
                              Width, Height, nStartAngle, nSweepAngle);
                }
            }

            gp.CloseFigure();

            return(gp);
        }
        /// <summary>
        /// Assigment sets from another
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        public void Set(C2DPolyBase Other)
        {
            Clear();

            Lines.MakeValueCopy(Other.Lines);

            BoundingRect.Set(Other.BoundingRect);

            for (var i = 0; i < Other.LineRects.Count; i++)
            {
                LineRects.Add(new C2DRect(Other.LineRects[i]));
            }
        }
Beispiel #10
0
        /// <summary>
        /// Assigment sets from another
        /// </summary> 
        /// <param name="Other">The other polygon.</param> 
        public void Set(C2DPolyBase Other)
        {
	        Clear();

	        Lines.MakeValueCopy(Other.Lines);

	        BoundingRect.Set(Other.BoundingRect);

	        for (int i = 0 ; i < Other.LineRects.Count ; i ++)
	        {
		        LineRects.Add(new C2DRect( Other.LineRects[i]) );
	        }
        }
 /// <summary>
 /// Draws a polygon
 /// </summary>
 public void Draw(C2DPolyBase Poly, Graphics graphics, Pen pen)
 {
     for (int i = 0; i < Poly.Lines.Count; i++)
     {
         if (Poly.Lines[i] is C2DLine)
         {
             Draw(Poly.Lines[i] as C2DLine, graphics, pen);
         }
         else if (Poly.Lines[i] is C2DArc)
         {
             Draw(Poly.Lines[i] as C2DArc, graphics, pen);
         }
     }
 }
Beispiel #12
0
 /// <summary>
 /// Draws a polygon
 /// </summary>
 public void Draw(C2DPolyBase Poly, Graphics graphics, Pen pen)
 {
     for (int i = 0; i < Poly.Lines.Count; i++)
     {
         if (Poly.Lines[i] is C2DLine)
         {
             Draw(Poly.Lines[i] as C2DLine, graphics, pen);
         }
         else if (Poly.Lines[i] is C2DArc)
         {
             Draw(Poly.Lines[i] as C2DArc, graphics, pen);
         }
     }
 }
Beispiel #13
0
        /// <summary>
        /// True if this overlaps the other.
        /// </summary>
        /// <param name="Other">Other polygon to test for.</param>
        public bool Overlaps(C2DPolyBase Other)
        {
            if (!_Rim.Overlaps(Other))
            {
                return(false);
            }

            for (var i = 0; i < _Holes.Count; i++)
            {
                if (_Holes[i].Contains(Other))
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #14
0
        /// <summary>
        /// True if this crosses the other polygon.
        /// </summary>
        /// <param name="Poly">Polygon to test for.</param>
        public bool Crosses(C2DPolyBase Poly)
        {
            if (_Rim.Crosses(Poly))
            {
                return(true);
            }

            for (var i = 0; i < _Holes.Count; i++)
            {
                if (_Holes[i].Crosses(Poly))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #15
0
        /// <summary>
        /// Polygon entirely inside test.
        /// </summary>
        /// <param name="Polygon">Polygon to test for.</param>
        public bool Contains(C2DPolyBase Polygon)
        {
            if (!_Rim.Contains(Polygon))
            {
                return(false);
            }

            for (var i = 0; i < _Holes.Count; i++)
            {
                if (_Holes[i].Overlaps(Polygon))
                {
                    return(false);
                }
            }

            return(true);
        }
        /// <summary>
        /// True if it crosses the other.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        public bool Crosses(C2DPolyBase Other)
        {
            if (!BoundingRect.Overlaps(Other.BoundingRect))
            {
                return(false);
            }

            var Temp = new List <C2DPoint>();

            for (var i = 0; i < Lines.Count; i++)
            {
                if (Other.Crosses(Lines[i], Temp))
                {
                    return(true);
                }
            }
            return(false);
        }
        /// <summary>
        /// True if this overlaps the other.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        public bool Overlaps(C2DPolyBase Other)
        {
            if (Lines.Count == 0 || Other.Lines.Count == 0)
            {
                return(false);
            }

            if (Other.Contains(Lines[0].GetPointTo()))
            {
                return(true);
            }

            if (Crosses(Other))
            {
                return(true);
            }

            return(this.Contains(Other.Lines[0].GetPointTo()));
        }
        /// <summary>
        /// True if it entirely contains the other.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        public bool Contains(C2DPolyBase Other)
        {
            if (Other.Lines.Count == 0)
            {
                return(false);
            }

            if (!BoundingRect.Contains(Other.BoundingRect))
            {
                return(false);
            }

            if (!Contains(Other.Lines[0].GetPointFrom()))
            {
                return(false);
            }

            return(!this.Crosses(Other));
        }
        /// <summary>
        /// Intersection with another.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        /// <param name="IntersectionPts">Output. The intersection points.</param>
        public bool Crosses(C2DPolyBase Other, List <C2DPoint> IntersectionPts)
        {
            if (!BoundingRect.Overlaps(Other.BoundingRect))
            {
                return(false);
            }

            var IntPtsTemp = new List <C2DPoint>();
            var Index1     = new List <int>();
            var Index2     = new List <int>();

            Lines.GetIntersections(Other.Lines, IntPtsTemp, Index1, Index2,
                                   BoundingRect, Other.BoundingRect);

            var bResult = IntPtsTemp.Count > 0;

            IntersectionPts.InsertRange(0, IntPtsTemp);

            return(bResult);
        }
        /// <summary>
        /// Creates a path based on a polygon.
        /// </summary>
        private System.Drawing.Drawing2D.GraphicsPath CreatePath( C2DPolyBase Poly)
        {
            System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();

            if (Poly.Lines.Count == 0)
                return gp;

            for (int i = 0; i < Poly.Lines.Count; i++)
            {
                if (Poly.Lines[i] is C2DLine)
                {
                    C2DPoint ptFrom = Poly.Lines[i].GetPointFrom();
                    C2DPoint ptTo = Poly.Lines[i].GetPointTo();
                    ScaleAndOffSet(ptFrom);
                    ScaleAndOffSet(ptTo);
                    gp.AddLine((int)ptFrom.x, (int)ptFrom.y, (int)ptTo.x, (int)ptTo.y);
                }
                else if (Poly.Lines[i] is C2DArc)
                {

                    C2DRect Rect = new C2DRect();
                    int nStartAngle = 0;
                    int nSweepAngle = 0;

                    GetArcParameters(Poly.Lines[i] as C2DArc, Rect, ref nStartAngle, ref nSweepAngle);

                    if (nSweepAngle == 0)
                        nSweepAngle = 1;

                    int Width = (int)Rect.Width();
                    if (Width == 0)
                        Width = 1;
                    int Height = (int)Rect.Height();
                    if (Height == 0)
                        Height = 1;

                    gp.AddArc((int)Rect.TopLeft.x, (int)Rect.BottomRight.y,
                        Width, Height, nStartAngle, nSweepAngle);

                }
            }

            gp.CloseFigure();

            return gp;
        }
        /// <summary>
        /// True if this crosses the other polygon.
        /// </summary>
        /// <param name="Poly">Polygon to test for.</param> 
        public bool Crosses(C2DPolyBase Poly) 
        {
            if (_Rim.Crosses(Poly))
		        return true;

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        if(_Holes[i].Crosses(Poly))
			        return true;
	        }
	        return false;
        }
        /// <summary>
        /// Distance from the polygon provided.
        /// </summary>
        /// <param name="Poly">Polygon to find the distance to.</param> 
        /// <param name="ptOnThis">Closest point on this to recieve the result.</param> 
        /// <param name="ptOnOther">Closest point on the other to recieve the result.</param> 
        public double Distance(C2DPolyBase Poly, C2DPoint ptOnThis, C2DPoint ptOnOther) 
        {
	        C2DPoint ptOnThisResult = new C2DPoint();
	        C2DPoint ptOnOtherResult = new C2DPoint();


            double dResult = _Rim.Distance(Poly, ptOnThis, ptOnOther);

	        if (dResult == 0)
		        return 0;

		    ptOnThisResult.Set(ptOnThis); 
		    ptOnOtherResult.Set(ptOnOther); 

	        bool bInside = dResult < 0;
	        dResult = Math.Abs(dResult);

	        for (int i = 0; i < _Holes.Count; i++)
	        {
		        double dDist = _Holes[i].Distance(Poly, ptOnThis, ptOnOther); 
		        if (dDist == 0)
			        return 0;
        		

		        if (dDist < 0)
			        bInside = false;
		        if (Math.Abs(dDist) < dResult)
		        {
				    ptOnThisResult.Set(ptOnThis); 
				    ptOnOtherResult.Set(ptOnOther); 

			        dResult = Math.Abs(dDist);
		        }
	        }

		    ptOnThis.Set(ptOnThisResult); 
		    ptOnOther.Set(ptOnOtherResult); 

	        if (bInside)
		        return dResult;
	        else
		        return - dResult;
        }
 /// <summary>
 /// Hole addition.
 /// </summary>
 public void AddHole(C2DPolyBase Poly)
 {
     _Holes.Add(Poly);
 }
Beispiel #24
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.
            C2DPointSet IntPoints = new C2DPointSet();
            List<int> Indexes1 = new List<int>();
            List<int> 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.
            C2DPointSet 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);
        }
Beispiel #25
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);
        }
Beispiel #26
0
        /// <summary>
        /// True if this overlaps the other.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        public bool Overlaps(C2DPolyBase Other)
        {
            if (Lines.Count == 0 || Other.Lines.Count == 0)
                return false;

            if (Other.Contains(Lines[0].GetPointTo()))
                return true;

            if (Crosses(Other))
                return true;

            return (this.Contains(Other.Lines[0].GetPointTo()));
        }
 /// <summary>
 /// Hole addition.
 /// </summary>
 public new void AddHole(C2DPolyBase Poly)
 {
     if (Poly is C2DPolygon)
     {
         _Holes.Add(Poly);
     }
     else
     {
         Debug.Assert(false, "Invalid Hole type");
     }
 }
Beispiel #28
0
 /// <summary>
 /// Hole assignment.
 /// </summary>
 public void SetHole(int i, C2DPolyBase Poly)
 {
     _Holes[i] = Poly;
 }
Beispiel #29
0
 /// <summary>
 /// Hole addition.
 /// </summary>
 public void AddHole(C2DPolyBase Poly)
 {
     _Holes.Add(Poly);
 }
        /// <summary>
        /// Distance of the poly from the shape.
        /// </summary>
        /// <param name="Other">The other polygon test.</param>
        /// <param name="ptOnThis">Output. The closest point on this.</param>
        /// <param name="ptOnOther">The closest point on the other.</param>
        public double Distance(C2DPolyBase Other, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
            if (Lines.Count == 0)
            {
                return(0);
            }

            if (Other.Lines.Count == 0)
            {
                return(0);
            }

            if (Other.LineRects.Count != Other.Lines.Count)
            {
                return(0);
            }

            if (Lines.Count != LineRects.Count)
            {
                return(0);
            }

            // First we find the closest line rect to the other's bounding rectangle.
            var    usThisClosestLineGuess = 0;
            var    OtherBoundingRect      = Other.BoundingRect;
            double dClosestDist           = LineRects[0].Distance(OtherBoundingRect);

            for (var i = 1; i < LineRects.Count; i++)
            {
                double dDist = LineRects[i].Distance(OtherBoundingRect);
                if (dDist < dClosestDist)
                {
                    dClosestDist           = dDist;
                    usThisClosestLineGuess = i;
                }
            }
            // Now cycle through all the other poly's line rects to find the closest to the
            // guessed at closest line on this.
            var usOtherClosestLineGuess = 0;

            dClosestDist = Other.LineRects[0].Distance(LineRects[usThisClosestLineGuess]);
            for (var j = 1; j < Other.LineRects.Count; j++)
            {
                double dDist = Other.LineRects[j].Distance(LineRects[usThisClosestLineGuess]);
                if (dDist < dClosestDist)
                {
                    dClosestDist            = dDist;
                    usOtherClosestLineGuess = j;
                }
            }

            // Now we have a guess at the 2 closest lines.
            double dMinDistGuess = Lines[usThisClosestLineGuess].Distance(
                Other.Lines[usOtherClosestLineGuess],
                ptOnThis,
                ptOnOther);

            // If its 0 then return 0.
            if (dMinDistGuess == 0)
            {
                return(0);
            }

            var ptOnThisTemp  = new C2DPoint();
            var ptOnOtherTemp = new C2DPoint();

            // Now go through all of our line rects and only check further if they are closer
            // to the other's bounding rect than the min guess.
            for (var i = 0; i < Lines.Count; i++)
            {
                if (LineRects[i].Distance(OtherBoundingRect) < dMinDistGuess)
                {
                    for (var j = 0; j < Other.Lines.Count; j++)
                    {
                        double dDist = Lines[i].Distance(Other.Lines[j],
                                                         ptOnThisTemp,
                                                         ptOnOtherTemp);

                        if (dDist < dMinDistGuess)
                        {
                            ptOnThis.Set(ptOnThisTemp);
                            ptOnOther.Set(ptOnOtherTemp);

                            if (dDist == 0)
                            {
                                return(0);
                            }

                            dMinDistGuess = dDist;
                        }
                    }
                }
            }

            // if we are here, there is no intersection but the other could be inside this or vice-versa
            if (BoundingRect.Contains(Other.BoundingRect) &&
                Contains(ptOnOtherTemp))
            {
                dMinDistGuess *= -1.0;
            }
            else if (Other.BoundingRect.Contains(BoundingRect) &&
                     Other.Contains(ptOnThisTemp))
            {
                dMinDistGuess *= -1.0;
            }

            return(dMinDistGuess);
        }
 /// <summary>
 /// Constructor sets from another
 /// </summary>
 /// <param name="Other">The other polygon.</param>
 public C2DPolyBase(C2DPolyBase Other)
 {
     Set(Other);
 }
Beispiel #32
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">Other polygon to set this to.</param>
 public C2DHoledPolyArc(C2DPolyBase Other)
 {
     _Rim = new C2DPolyArc(Other);
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">Other polygon to set this to.</param> 
 public C2DHoledPolygon(C2DPolyBase Other)
 {
     _Rim = new C2DPolygon(Other);
 }
         /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">Other polygon to set this to.</param> 
 public C2DHoledPolyArc(C2DPolyBase Other)
 {
     _Rim = new C2DPolyArc(Other);
 }
Beispiel #35
0
        /// <summary>
        /// Draws a polygon filled.
        /// </summary>
        public void DrawFilled(C2DPolyBase Poly, Graphics graphics, Brush brush)
        {
            System.Drawing.Drawing2D.GraphicsPath gp = CreatePath(Poly);

            graphics.FillPath(brush, gp);
        }
Beispiel #36
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);
 }
        /// <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;
                }
            }
        }
Beispiel #38
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;
		        }
                       
            }
        }
Beispiel #39
0
        /// <summary>
        /// True if it entirely contains the other.
        /// </summary> 
        /// <param name="Other">The other polygon.</param> 
        public bool Contains(C2DPolyBase Other)
        {
            if (Other.Lines.Count == 0)
                return false;

            if (!BoundingRect.Contains(Other.BoundingRect))
                return false;

            if (!Contains(Other.Lines[0].GetPointFrom()))
                return false;

            return !this.Crosses(Other);
        }
 /// <summary>
 /// Hole assignment.
 /// </summary>
 public void SetHole(int i, C2DPolyBase Poly)
 {
     _Holes[i] = Poly;
 }
Beispiel #41
0
        /// <summary>
        /// Distance of the poly from the shape. 
        /// </summary> 
        /// <param name="Other">The other polygon test.</param> 
        /// <param name="ptOnThis">Output. The closest point on this.</param> 
        /// <param name="ptOnOther">The closest point on the other.</param> 
        public double Distance(C2DPolyBase Other, C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
	        if (Lines.Count == 0)
		        return 0;

	        if (Other.Lines.Count == 0)
		        return 0;

	        if (Other.LineRects.Count != Other.Lines.Count)
		        return 0;

	        if (Lines.Count != LineRects.Count)
		        return 0;

	        // First we find the closest line rect to the other's bounding rectangle.
	        int usThisClosestLineGuess = 0;
	        C2DRect OtherBoundingRect = Other.BoundingRect;
	        double dClosestDist = LineRects[0].Distance(OtherBoundingRect);
	        for (int i = 1; i < LineRects.Count; i++)
	        {
		        double dDist = LineRects[i].Distance(OtherBoundingRect);
		        if (dDist < dClosestDist)
		        {
			        dClosestDist = dDist;
			        usThisClosestLineGuess = i;
		        }
	        }
	        // Now cycle through all the other poly's line rects to find the closest to the
	        // guessed at closest line on this.
	        int usOtherClosestLineGuess = 0;
	        dClosestDist = Other.LineRects[0].Distance(LineRects[usThisClosestLineGuess]);
	        for (int j = 1; j < Other.LineRects.Count; j++)
	        {
		        double dDist = Other.LineRects[j].Distance(LineRects[usThisClosestLineGuess]);
		        if (dDist < dClosestDist)
		        {
			        dClosestDist = dDist;
			        usOtherClosestLineGuess = j;
		        }
	        }

	        // Now we have a guess at the 2 closest lines.
	        double dMinDistGuess = Lines[usThisClosestLineGuess].Distance(
							        Other.Lines[usOtherClosestLineGuess],
							        ptOnThis,
							        ptOnOther);
	        // If its 0 then return 0.
	        if (dMinDistGuess == 0)
		        return 0;

	        C2DPoint ptOnThisTemp = new C2DPoint();
	        C2DPoint ptOnOtherTemp = new C2DPoint();

	        // Now go through all of our line rects and only check further if they are closer
	        // to the other's bounding rect than the min guess.
	        for (int i = 0; i < Lines.Count; i++)
	        {
		        if (LineRects[i].Distance( OtherBoundingRect ) <  dMinDistGuess)
		        {
			        for (  int j = 0 ; j < Other.Lines.Count ; j++)
			        {
				        double dDist = Lines[i].Distance(Other.Lines[j],
													        ptOnThisTemp,
													        ptOnOtherTemp);
        				
				        if (dDist < dMinDistGuess)
				        {	
						    ptOnThis.Set(ptOnThisTemp);
					        ptOnOther.Set(ptOnOtherTemp);

					        if (dDist == 0)
						        return 0;

					        dMinDistGuess = dDist; 
				        }
			        }
		        }
	        }

	        // if we are here, there is no intersection but the other could be inside this or vice-versa
	        if ( BoundingRect.Contains(Other.BoundingRect)
		        && Contains(ptOnOtherTemp)  )
	        {
		        dMinDistGuess *= -1.0;
	        }
	        else if ( Other.BoundingRect.Contains(BoundingRect)
		        && Other.Contains( ptOnThisTemp ))
	        {
		        dMinDistGuess *= -1.0;
	        }

	        return dMinDistGuess;
        }
Beispiel #42
0
        /// <summary>
        /// Function to convert polygons to complex polygons. Assigning holes to those that are contained.
        /// The set of holed polygons will be filled from the set of simple polygons.
        /// </summary>
        /// <param name="HoledPolys">Holed polygon set.</param>
        /// <param name="Polygons">Simple polygon set.</param>
        public static void PolygonsToHoledPolygons(List <C2DHoledPolyBase> HoledPolys,
                                                   List <C2DPolyBase> Polygons)
        {
            List <C2DPolyBase>      Unmatched     = new List <C2DPolyBase>();
            List <C2DHoledPolyBase> NewHoledPolys = new List <C2DHoledPolyBase>();

            for (int i = Polygons.Count - 1; i >= 0; i--)
            {
                bool bMatched = false;

                C2DPolyBase pPoly = Polygons[i];
                Polygons.RemoveAt(i);

                // Cycle through the newly created polygons to see if it's a hole.
                for (int p = 0; p < NewHoledPolys.Count; p++)
                {
                    if (NewHoledPolys[p].Rim.Contains(pPoly.Lines[0].GetPointFrom()))
                    {
                        NewHoledPolys[p].AddHole(pPoly);
                        bMatched = true;
                        break;
                    }
                }
                // If its not then compare it to all the other unknowns.
                if (!bMatched)
                {
                    int u = 0;

                    bool bKnownRim = false;

                    while (u < Unmatched.Count)
                    {
                        if (!bKnownRim && Unmatched[u].Contains(pPoly.Lines[0].GetPointFrom()))
                        {
                            // This is a hole.
                            NewHoledPolys.Add(new C2DHoledPolyBase());
                            NewHoledPolys[NewHoledPolys.Count - 1].Rim = Unmatched[u];
                            Unmatched.RemoveAt(u);
                            NewHoledPolys[NewHoledPolys.Count - 1].AddHole(pPoly);
                            bMatched = true;
                            break;
                        }
                        else if (pPoly.Contains(Unmatched[u].Lines[0].GetPointFrom()))
                        {
                            //	int nCount = OverlapPolygons->GetCount();
                            // This is a rim.
                            if (!bKnownRim)
                            {
                                // If we haven't alreay worked this out then record that its a rim
                                // and set up the new polygon.
                                bKnownRim = true;
                                NewHoledPolys.Add(new C2DHoledPolyBase());
                                NewHoledPolys[NewHoledPolys.Count - 1].Rim = pPoly;
                                NewHoledPolys[NewHoledPolys.Count - 1].AddHole(Unmatched[u]);
                                Unmatched.RemoveAt(u);
                            }
                            else
                            {
                                // We already worked out this was a rim so it must be the last polygon.
                                NewHoledPolys[NewHoledPolys.Count - 1].AddHole(Unmatched[u]);
                                Unmatched.RemoveAt(u);
                            }
                            // Record that its been matched.
                            bMatched = true;
                        }
                        else
                        {
                            // Only if there was no match do we increment the counter.
                            u++;
                        }
                    }
                }

                if (!bMatched)
                {
                    Unmatched.Add(pPoly);
                }
            }

            for (int i = 0; i < Unmatched.Count; i++)
            {
                C2DHoledPolyBase NewHoled = new C2DHoledPolyBase();
                NewHoled.Rim = Unmatched[i];
                HoledPolys.Add(NewHoled);
            }

            HoledPolys.AddRange(NewHoledPolys);
        }
Beispiel #43
0
        /// <summary>
	    /// Constructor sets from another
        /// </summary> 
        /// <param name="Other">The other polygon.</param> 
	    public C2DPolyBase(C2DPolyBase Other)
        {
        	Set(Other);
        }
        /// <summary>
        /// Polygon entirely inside test.
        /// </summary>
        /// <param name="Polygon">Polygon to test for.</param> 
        public bool Contains(C2DPolyBase Polygon) 
        {
            if (!_Rim.Contains(Polygon))
		        return false;

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        if (_Holes[i].Overlaps(Polygon))
			        return false;
	        }

	        return true;
        }
Beispiel #45
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];
        }
        /// <summary>
        /// True if this overlaps the other.
        /// </summary>
        /// <param name="Other">Other polygon to test for.</param> 
        public bool Overlaps(C2DPolyBase Other) 
        {
            if (!_Rim.Overlaps(Other))
		        return false;

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        if (_Holes[i].Contains(Other))
			        return false;
	        }
	        return true;
        }
Beispiel #47
0
        /// <summary>
        /// True if it crosses the other.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        public bool Crosses(C2DPolyBase Other)
        {
	        if (!BoundingRect.Overlaps(Other.BoundingRect))
		        return false;

            List<C2DPoint> Temp = new List<C2DPoint>();
	        for (int i = 0; i < Lines.Count; i++)
	        {
                if (Other.Crosses(Lines[i], Temp))
			        return true;
	        }
	        return false;

        }
        /// <summary>
        /// Draws a polygon filled.
        /// </summary>
        public void DrawFilled(C2DPolyBase Poly, Graphics graphics, Brush brush)
        {
            System.Drawing.Drawing2D.GraphicsPath gp = CreatePath(Poly);

            graphics.FillPath(brush, gp);
        }
Beispiel #49
0
        /// <summary>
        /// Intersection with another.
        /// </summary>
        /// <param name="Other">The other polygon.</param>
        /// <param name="IntersectionPts">Output. The intersection points.</param>
        public bool Crosses(C2DPolyBase Other, List<C2DPoint> IntersectionPts)
        {
            if (!BoundingRect.Overlaps(Other.BoundingRect))
                return false;

            List<C2DPoint> IntPtsTemp = new List<C2DPoint>();
            List<int> Index1 = new List<int>();
            List<int> Index2 = new List<int>();

            Lines.GetIntersections(Other.Lines, IntPtsTemp, Index1, Index2,
                                    BoundingRect, Other.BoundingRect);

            bool bResult = IntPtsTemp.Count > 0;

            IntersectionPts.InsertRange(0, IntPtsTemp);

            return bResult;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">The other polygon.</param> 
 public C2DPolyArc(C2DPolyBase Other)
     : base(Other)
 {
 }
Beispiel #51
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">Other polygon to set this to.</param>
 public C2DHoledPolygon(C2DPolyBase Other)
 {
     _Rim = new C2DPolygon(Other);
 }
 /// <summary>
 /// Hole access.
 /// </summary>
 public new void SetHole(int i, C2DPolyBase Poly)
 {
     if (Poly is C2DPolygon)
     {
         _Holes[i] = Poly;
     }
     else
     {
         Debug.Assert(false, "Invalid Hole type");
     }
 }
 /// <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);
 }
Beispiel #54
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="Other">The other polygon.</param>
 public C2DPolyArc(C2DPolyBase Other) : base(Other)
 {
 }
 /// <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);
 }