/// <summary> /// Find the intersection points of lines that cross a polygon /// </summary> /// <param name="lineFeatureSet">The line features</param> /// <param name="polygon">The polygon feature</param> /// <param name="intersectsPerLineSeg">Output array of intersection counts</param> /// <param name="intersectionPts">Output array of intersection points</param> /// <param name="polyIntersectLocs">Output array of intersection locations in reference to polygon vertex indices</param> /// <returns></returns> public static int FindIntersections( IFeatureSet lineFeatureSet, IFeature polygon, out int[] intersectsPerLineSeg, out Point[][] intersectionPts, out int[][] polyIntersectLocs) { int numSignChanges = 0; // tracks number of determinant sign changes int numLines = lineFeatureSet.Features.Count; int numVerticies = polygon.NumPoints; int[][] detSigns = new int[numLines][]; bool[][] signChanges = new bool[numLines][]; // keeps track of where sign changes occur int[][] changeLocations = new int[numLines][]; int[] intersectsPerLine = new int[numLines]; Point[][] intersectPts = new Point[numLines][]; IList<Coordinate> coorPoly = polygon.Coordinates; // ICoordinate[] secCoor = new ICoordinate[2]; for (int lineNo = 0; lineNo <= numLines - 1; lineNo++) { IFeature line = lineFeatureSet.Features[lineNo]; IList<Coordinate> coorLine = line.Coordinates; int numChangesPerLine = 0; detSigns[lineNo] = new int[numVerticies]; signChanges[lineNo] = new bool[numVerticies]; intersectPts[lineNo] = new Point[numVerticies]; changeLocations[lineNo] = new int[numVerticies]; for (int vertNo = 0; vertNo <= numVerticies - 1; vertNo++) { intersectPts[lineNo][vertNo] = new Point(); Point intersectPt = new Point(); // Calculate the determinant (3x3 square matrix) double si = TurboDeterm( coorPoly[vertNo].X, coorLine[0].X, coorLine[1].X, coorPoly[vertNo].Y, coorLine[0].Y, coorLine[1].Y); // Check the determinant result switch (vertNo) { case 0: if (Math.Abs(si) <= FindIntersectionTolerance) { detSigns[lineNo][vertNo] = 0; // we have hit a vertex } else if (si > 0) { detSigns[lineNo][vertNo] = 1; // +'ve } else if (si < 0) { detSigns[lineNo][vertNo] = -1; // -'ve } signChanges[lineNo][0] = false; // First element will NEVER be a sign change break; default: if (Math.Abs(si) <= FindIntersectionTolerance) { detSigns[lineNo][vertNo] = 0; } else if (si > 0) { detSigns[lineNo][vertNo] = 1; } else if (si < 0) { detSigns[lineNo][vertNo] = -1; } // Check for sign change if (detSigns[lineNo][vertNo - 1] != detSigns[lineNo][vertNo]) { IList<Coordinate> secCoor = new List<Coordinate> { coorPoly[vertNo - 1], coorPoly[vertNo] }; // calculate the actual intercept point LineString polyTestLine1 = new LineString(secCoor); secCoor = new List<Coordinate> { coorLine[0], coorLine[1] }; LineString polyTestLine2 = new LineString(secCoor); bool validIntersect = polyTestLine1.Intersects(polyTestLine2); IGeometry inPt = polyTestLine1.Intersection(polyTestLine2); if (inPt.Coordinates.Count == 1) { intersectPt = new Point(inPt.Coordinate); } if (validIntersect) { signChanges[lineNo][vertNo] = true; numSignChanges += 1; numChangesPerLine += 1; intersectsPerLine[lineNo] = numChangesPerLine; // we want to store the valid intersect pts at the // beginning of the array so we don't have to search for them intersectPts[lineNo][numChangesPerLine - 1] = intersectPt; // keep track of where the intersect occurs in reference to polygon changeLocations[lineNo][numChangesPerLine - 1] = vertNo; // intersect pt occurs between vertNo-1 and vertNo } else { signChanges[lineNo][vertNo] = false; } } else { signChanges[lineNo][vertNo] = false; } break; } // end of switch } } polyIntersectLocs = changeLocations; intersectionPts = intersectPts; intersectsPerLineSeg = intersectsPerLine; return numSignChanges; }
/// <summary> /// Returns true if the element intersect the rectangle from the parent class /// </summary> /// <param name="rect">The rectangle to test must be in the virtual modeling coordinant plane</param> /// <returns></returns> public override bool ElementInRectangle(Rectangle rect) { IGeometry rectanglePoly; if ((rect.Height == 0) && (rect.Width == 0)) { rectanglePoly = new Topology.Point(rect.X, rect.Y); } else if (rect.Width == 0) { Topology.Point[] rectanglePoints = new Topology.Point[2]; rectanglePoints[0] = new Topology.Point(rect.X, rect.Y); rectanglePoints[1] = new Topology.Point(rect.X, rect.Y + rect.Height); rectanglePoly = new LineString(rectanglePoints); } else if (rect.Height == 0) { Topology.Point[] rectanglePoints = new Topology.Point[2]; rectanglePoints[0] = new Topology.Point(rect.X, rect.Y); rectanglePoints[1] = new Topology.Point(rect.X + rect.Width, rect.Y); rectanglePoly = new LineString(rectanglePoints); } else { Topology.Point[] rectanglePoints = new Topology.Point[5]; rectanglePoints[0] = new Topology.Point(rect.X, rect.Y); rectanglePoints[1] = new Topology.Point(rect.X, rect.Y + rect.Height); rectanglePoints[2] = new Topology.Point(rect.X + rect.Width, rect.Y + rect.Height); rectanglePoints[3] = new Topology.Point(rect.X + rect.Width, rect.Y); rectanglePoints[4] = new Topology.Point(rect.X, rect.Y); rectanglePoly = new Polygon(new LinearRing(rectanglePoints)); } if (Shape == ModelShape.Arrow) { Topology.Point[] arrowPoints = new Topology.Point[_arrowPath.PointCount]; for (int i = 0; i < _arrowPath.PointCount; i++) { arrowPoints[i] = new Topology.Point(_arrowPath.PathPoints[i].X + Location.X, _arrowPath.PathPoints[i].Y + Location.Y); } LineString arrowLine = new LineString(arrowPoints); return (arrowLine.Intersects(rectanglePoly)); } return false; }