Beispiel #1
0
        public void SnapToOriginInPlace(IList <C2DPoint> input)
        {
            var minXy = MinMax(input);

            for (var i = 0; i < input.Count; ++i)
            {
                input[i] = new C2DPoint(input[i].X - minXy.Item1, input[i].Y - minXy.Item2);
            }
            var poly = new C2DPolygon(input.ToList(), true);

            poly.RandomPerturb();
            var pointsCopy = new C2DPointSet();

            poly.GetPointsCopy(pointsCopy);
            for (var i = 0; i < pointsCopy.Count; ++i)
            {
                input[i] = pointsCopy[i];
            }
        }
Beispiel #2
0
        /// <summary>
        /// True if part of this line is above the other. Returns the point 
        /// on this and on the other.
        /// </summary>
        /// <param name="Other"></param>
        /// <param name="dVerticalDistance"></param>
        /// <param name="ptOnThis"></param>
        /// <param name="ptOnOther"></param>
        /// <returns></returns>
        public bool OverlapsAbove(C2DLine Other, ref double dVerticalDistance, 
									        C2DPoint ptOnThis, C2DPoint ptOnOther)
        {
	        // Get the 2 points for both lines
	        C2DPoint OtherTo = new C2DPoint(Other.point.x + Other.vector.i, Other.point.y + Other.vector.j);
	        C2DPoint ThisTo = new C2DPoint(point.x + vector.i, point.y + vector.j);
	        // Make an interval for both in the x plane
	        CInterval iThis = new CInterval( point.x, point.x);
	        iThis.ExpandToInclude( ThisTo.x );

	        CInterval iOther = new CInterval( Other.point.x, Other.point.x);
	        iOther.ExpandToInclude( OtherTo.x );
	        // This is an interval for the overlap between the 2
	        CInterval iOverlap = new CInterval();
	        // If there is an overlap...
	        if (iThis.Overlaps(iOther, iOverlap))
	        {
		        double dThisYMin;
		        double dThisYMax;

		        double dOtherYMin;
		        double dOtherYMax;
		        // If the line is vertical then y at the x min / max can be set to the ends of the line.
		        if (vector.i == 0)
		        {
			        dThisYMin = point.y;
			        dThisYMax = ThisTo.y;
		        }
		        else	// otherwise, caluclate the y values at the interval ends
		        {
			        dThisYMin = GetY(iOverlap.dMin);
			        dThisYMax = GetY(iOverlap.dMax);
		        }
		        // Now do the same for the other line
		        if (Other.vector.i == 0)
		        {
			        dOtherYMin = Other.point.y;
			        dOtherYMax = OtherTo.y;
		        }
		        else
		        {
			        dOtherYMin = Other.GetY(iOverlap.dMin);
			        dOtherYMax = Other.GetY(iOverlap.dMax);
		        }
        		
		        // Now find the distance between the 2 at the ends
		        double dDistMin = dThisYMin - dOtherYMin;
		        double dDistMax = dThisYMax - dOtherYMax;
		        // If they are both > 0 then no intersection
		        if ( (dDistMin > 0) && (dDistMax > 0))
		        {
			        dDistMin = Math.Abs( dDistMin);
                    dDistMax = Math.Abs(dDistMax);
			        // find which one is smallest
			        if ( dDistMin > dDistMax)
			        {	
				        dVerticalDistance = dDistMax;	// distance at the max is smallest
				        ptOnThis.x = iOverlap.dMax;
				        ptOnThis.y = dThisYMax;
				        ptOnOther.x = iOverlap.dMax;
				        ptOnOther.y = dOtherYMax;
			        }
			        else
			        {
				        dVerticalDistance = dDistMin;  // distance at the min is smallest
				        ptOnThis.x = iOverlap.dMin;
				        ptOnThis.y = dThisYMin;
				        ptOnOther.x = iOverlap.dMin;
				        ptOnOther.y = dOtherYMin;
			        }

			        return true;
		        }	
		        else if ( (dDistMin < 0) && (dDistMax < 0)) // This is below.
		        {
			        return false;
		        }
		        else
		        {
			        // find the intersection.
			        dVerticalDistance = 0;
			        C2DPointSet pts = new C2DPointSet();
			        if(this.Crosses(Other, pts))
			        {
				        ptOnThis = pts[0];
				        ptOnOther = ptOnThis;
			        }
			        else
			        {
				        Debug.Assert(false);
			        }
		        }
        	
		        return true;
	        }
	        else
	        {
		        return false;
	        }

        }
Beispiel #3
0
        /// <summary>
        /// Returns the lines that make up this defined by the points which are assumed
        /// to be on this line. i.e. splits the line up.
        /// </summary>
        /// <param name="PtsOnLine">The point set defining how this is to be broken up.</param>
        /// <param name="LineSet">Output. The sub lines.</param>
        public override void GetSubLines(List<C2DPoint> PtsOnLine,  List<C2DLineBase> LineSet)
        {
	        // if there are no points on the line to split on then add a copy of this and return.
	        int usPointsCount = PtsOnLine.Count;
	        if (usPointsCount == 0 )
	        {
		        LineSet.Add(new C2DLine(this));
	        }
	        else
	        {
		        C2DPointSet TempPts = new C2DPointSet();
		        TempPts.MakeCopy(PtsOnLine);

		        if (usPointsCount > 1) // They need sorting
		        {
			        // Now sort the points according to the order in which they will be encountered
			        TempPts.SortByDistance(point);
		        }

		        // Add the line from the start of this to the first.
		        LineSet.Add(new C2DLine(point, TempPts[0]  ));

		        // Add all the sub lines.
		        for (int i = 1; i < usPointsCount; i++)
			        LineSet.Add(new C2DLine(TempPts[i - 1], TempPts[i]));

		        // Add the line from the last point on this to the end of this.
                LineSet.Add(new C2DLine(TempPts[TempPts.Count - 1], GetPointTo()));
	        }

            Debug.Assert(LineSet.Count == (PtsOnLine.Count + 1));

        }
        /// <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 crosses the ray, returns the intersection points.
        /// </summary>
        /// <param name="Ray">Ray to test for.</param> 
        /// <param name="IntersectionPts">Intersection points.</param> 
        public bool CrossesRay(C2DLine Ray, C2DPointSet IntersectionPts) 
        {
	        C2DPointSet IntPts = new C2DPointSet();

            _Rim.CrossesRay(Ray, IntPts);

	        IntersectionPts.ExtractAllOf(IntPts);

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        if (_Holes[i].CrossesRay(Ray, IntPts))
		        {
			        double dDist = Ray.point.Distance(IntPts[0]);
			        int nInsert = 0;

			        while (nInsert < IntersectionPts.Count && 
				        Ray.point.Distance( IntersectionPts[nInsert]) < dDist )
			        {
				        nInsert++;
			        }

			        IntersectionPts.InsertRange(nInsert, IntPts);
		        }
	        }

	        return (IntersectionPts.Count > 0);

        }
        /// <summary>
        /// True if this crosses the line.
        /// </summary>
        /// <param name="Line">Line to test for.</param> 
        /// <param name="IntersectionPts">Point set to recieve the intersections.</param> 
        public bool Crosses(C2DLineBase Line, C2DPointSet IntersectionPts) 
        {
	        C2DPointSet IntPts = new C2DPointSet();

            _Rim.Crosses(Line, IntPts);

	        for (int i = 0 ; i < _Holes.Count; i++)
	        {
		        _Holes[i].Crosses(Line, IntPts);
	        }
	        bool bResult = (IntPts.Count != 0);
		    IntersectionPts.ExtractAllOf(IntPts);

	        return (bResult);

        }
        /// <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);
        }
        /// <summary>
        /// True if the point is in the shape.
        /// </summary> 
        /// <param name="pt">The point to test set.</param> 
	    public bool Contains(C2DPoint pt)
        {
	        if (!BoundingRect.Contains(pt))
		        return false;

	        C2DPointSet IntersectedPts = new C2DPointSet ();

	        C2DLine Ray = new C2DLine(pt, new C2DVector(BoundingRect.Width(), 0.000001)); // Make sure to leave

	        if (!this.Crosses(Ray,  IntersectedPts))
		        return false;
	        else
	        {
		        IntersectedPts.SortByDistance(Ray.point);
		        if ( IntersectedPts[0].PointEqualTo(pt))
		        {
			        // For integers, the pt can start On a line, meaning it's INSIDE, but the ray could cross again
			        // so just return true. Because the equality test is really a test for proximity, this leads to the
			        // possibility that a point could lie just outside the shape but be considered to be inside. This would
			        // only be a problem with very small shapes that are a very long way from the origin. E.g. a 1m2 object
			        // 1 million metres from the origin and a point 0.1mm away from the edge would give rise to a relative 
			        // difference of 0.0001 / 1000000 = 0.000000001 which would just be consider to be inside.
			        return true;
		        }
		        else
		        {
			        // Return true if the ray 
			        return (IntersectedPts.Count & (int)1) > 0;
		        }
	        }

        }
        /// <summary>
        /// Returns the routes (collection of lines and sublines) either inside or outside another
        /// Given the intersection points.
        /// </summary>
        /// <param name="IntPts">The intersection points of this with the other polygon.</param>
        /// <param name="IntIndexes">The corresponding line indexes.</param>
        /// <param name="Routes">Output. The routes to get the result.</param>
        /// <param name="bStartInside">True if this polygon starts inside the other.</param>
        /// <param name="bRoutesInside">True if we require routes of this polygon inside the other.</param>    
        public void GetRoutes(C2DPointSet IntPts, List<int> IntIndexes,
            C2DLineBaseSetSet Routes, bool bStartInside, bool bRoutesInside)
        {
            
	        // Make sure the intersection indexes and points are the same size.
	        if (IntIndexes.Count != IntPts.Count )
	        {
		        Debug.Assert(false);
		        return;
	        }
	        // Set up a new collection of routes.
	        C2DLineBaseSetSet NewRoutes = new C2DLineBaseSetSet();
	        // If the polygon has no points then return.
	        if ( _Lines.Count < 1) 
		        return;
	        // Sort the intersections by index so we can go through them in order.
            IntPts.SortByIndex( IntIndexes );   
            
            // Set the inside / outside flag to the same as the start inside / outside flag.
	        bool bInside = bStartInside;
	        // If we are inside and want route inside or outside and want routes outside then add a new route.
	        if (bInside == bRoutesInside)
	        {
		        NewRoutes.Add(new C2DLineBaseSet());
	        }

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

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

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

			        while (SubLines.Count > 1)
			        {
				        if (bInside == bRoutesInside)
				        {
					        // We have 1. Left and want route in. OR 2. Entered and want routes out.
					        NewRoutes[NewRoutes.Count - 1].Add( SubLines.ExtractAt(0) );
					        bInside = true ^ bRoutesInside;
				        }
				        else
				        {
					        NewRoutes.Add(new C2DLineBaseSet());
					        bInside = false ^ bRoutesInside;
					        SubLines.RemoveAt(0);
				        }
			        }
			        if (bInside == bRoutesInside)
				        NewRoutes[NewRoutes.Count - 1].Add( SubLines.ExtractAt(SubLines.Count - 1 ) );
			        else
				        SubLines.RemoveAt(SubLines.Count - 1);
		        }
		        // Otherwise, if we are e.g. inside and want routes in the keep adding the end poitn of the line.
		        else if (bInside == bRoutesInside)
		        {
			        NewRoutes[NewRoutes.Count - 1].AddCopy(  Lines[i] );
		        }

	        }
	        // Put all the new routes into the provided collection.
	        Routes.ExtractAllOf(NewRoutes);
        }
Beispiel #10
0
        /// <summary>
        /// True if it crosses the ray. Provides the intersection points.
        /// </summary>
        /// <param name="Ray">The infinite line.</param>
        /// <param name="IntersectionPts">Output. The intersection points.</param>
        public bool CrossesRay(C2DLine Ray, C2DPointSet IntersectionPts)
        {
            double dDist = Ray.point.Distance(BoundingRect.GetCentre());

            C2DLine LineTemp = new C2DLine(Ray);

            LineTemp.vector.SetLength(dDist + BoundingRect.Width() + BoundingRect.Height());

            return Crosses(LineTemp, IntersectionPts);

        }
Beispiel #11
0
        /// <summary>
        /// True if it crosses the line. Provides the intersection points.
        /// </summary>
        /// <param name="Line">The other line.</param>
        /// <param name="IntersectionPts">Output. The intersection points.</param>
        public bool Crosses(C2DLineBase Line, List<C2DPoint> IntersectionPts)
        {
	        C2DRect LineRect = new C2DRect();
	        Line.GetBoundingRect( LineRect);

	        if (!BoundingRect.Overlaps(LineRect))
		        return false;

	        Debug.Assert(Lines.Count == LineRects.Count);

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

	        C2DPointSet IntersectionTemp = new C2DPointSet();

	        bool bResult = false;

            for (int i = 0; i < this.Lines.Count; i++)
	        {
		        if (LineRects[i].Overlaps(LineRect) &&
			        Lines[i].Crosses(Line, IntersectionTemp as List<C2DPoint>))
		        {
			        bResult = true;
		        }
	        }

	        IntersectionPts.InsertRange(0, IntersectionTemp);

	        return bResult;
        }
Beispiel #12
0
        /// <summary>
        /// True if it entirely contains the line.
        /// </summary> 
        /// <param name="Line">The line to test.</param> 
        public bool Contains(C2DLineBase Line)
        {
            if (!Contains(Line.GetPointFrom()))
                return false;

            C2DPointSet Pts = new C2DPointSet();

            return !Crosses(Line, Pts);
        }
Beispiel #13
0
        /// <summary>
	    /// Returns the lines that go to make this up based on the set of points 
	    /// provided which are assumed to be on the line.
        /// </summary>
        /// <param name="PtsOnLine">The points defining how the line is to be split.</param> 
        /// <param name="LineSet">The line set to recieve the result.</param> 
        public override void GetSubLines(List<C2DPoint> PtsOnLine,  List<C2DLineBase> LineSet) 
        {
            
	        // if there are no points on the line to split on then add a copy of this and return.
	        int usPointsCount = PtsOnLine.Count;
	        if (usPointsCount == 0 )
	        {
		        LineSet.Add(new C2DArc(this));
		        return;
	        }
	        else
	        {
		        // Make a copy of the points for sorting.
		        C2DPointSet TempPts = new C2DPointSet();
		        TempPts.MakeCopy(PtsOnLine);

		        if (usPointsCount > 1) // They need sorting
		        {
			        // Make a line from the mid point of my line to the start
			        C2DLine CenToStart = new C2DLine( Line.GetMidPoint(), Line.point );
			        // Now sort the points according to the order in which they will be encountered
			        if (ArcOnRight)
				        TempPts.SortByAngleToLeft( CenToStart );
			        else
				        TempPts.SortByAngleToRight( CenToStart );
		        }

		        C2DPoint ptCentre = new C2DPoint(GetCircleCentre());

		        // Add the line from the start of this to the first.
		        C2DLine NewLine = new C2DLine( Line.point, TempPts[0] );
                LineSet.Add(new C2DArc(NewLine, Radius,
                                          NewLine.IsOnRight(ptCentre), ArcOnRight));

		        // Add all the sub lines.
		        for (int i = 1; i < usPointsCount; i++)
		        {
                    NewLine.Set(TempPts[i - 1], TempPts[i]);
                    LineSet.Add(new C2DArc(NewLine, Radius,
                                            NewLine.IsOnRight(ptCentre), ArcOnRight));
		        }
		        // Add the line from the last point on this to the end of this.
                NewLine.Set(TempPts[TempPts.Count - 1], Line.GetPointTo());
                LineSet.Add(new C2DArc(NewLine, Radius,
                                           NewLine.IsOnRight(ptCentre), ArcOnRight));
	        }
            
        }