private static ReferenceLineIntersectionResult GetReferenceLineIntersectionsResult(IEnumerable <Segment2D> surfaceLineSegments, IEnumerable <Segment2D> referenceLineSegments) { Point2D intersectionPoint = null; foreach (Segment2D surfaceLineSegment in surfaceLineSegments) { foreach (Segment2D referenceLineSegment in referenceLineSegments) { Segment2DIntersectSegment2DResult result = Math2D.GetIntersectionBetweenSegments(surfaceLineSegment, referenceLineSegment); if (result.IntersectionType == Intersection2DType.Intersects) { Point2D resultIntersectionPoint = result.IntersectionPoints[0]; if (intersectionPoint != null && !intersectionPoint.Equals(resultIntersectionPoint)) { // Early exit as multiple intersections is a return result: return(ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult()); } intersectionPoint = resultIntersectionPoint; } if (result.IntersectionType == Intersection2DType.Overlaps) { // Early exit as overlap is a return result: return(ReferenceLineIntersectionResult.CreateMultipleIntersectionsOrOverlapResult()); } } } return(intersectionPoint != null ? ReferenceLineIntersectionResult.CreateIntersectionResult(intersectionPoint) : ReferenceLineIntersectionResult.CreateNoSingleIntersectionResult()); }
public void CreateNoIntersectResult_ExpectedValues() { // Call Segment2DIntersectSegment2DResult result = Segment2DIntersectSegment2DResult.CreateNoIntersectResult(); // Assert Assert.AreEqual(Intersection2DType.DoesNotIntersect, result.IntersectionType); CollectionAssert.IsEmpty(result.IntersectionPoints); }
public void CreateIntersectionResult_ExpectedValues() { // Setup var point = new Point2D(1.1, 2.2); // Call Segment2DIntersectSegment2DResult result = Segment2DIntersectSegment2DResult.CreateIntersectionResult(point); // Assert Assert.AreEqual(Intersection2DType.Intersects, result.IntersectionType); CollectionAssert.AreEqual(new[] { point }, result.IntersectionPoints); }
private static IEnumerable <IEnumerable <Point2D> > CreateZoneAreas(IEnumerable <Point2D> waternetLineGeometry, IEnumerable <Point2D> phreaticLineGeometry) { var areas = new List <IEnumerable <Point2D> >(); Segment2D[] phreaticLineSegments = Math2D.ConvertPointsToLineSegments(phreaticLineGeometry).ToArray(); Segment2D[] waternetLineSegments = Math2D.ConvertPointsToLineSegments(waternetLineGeometry).ToArray(); var intersectionPoints = new List <Point2D>(); foreach (Segment2D phreaticLineSegment in phreaticLineSegments) { foreach (Segment2D waternetLineSegment in waternetLineSegments) { Segment2DIntersectSegment2DResult intersectionPointResult = Math2D.GetIntersectionBetweenSegments(phreaticLineSegment, waternetLineSegment); if (intersectionPointResult.IntersectionType == Intersection2DType.Intersects) { intersectionPoints.Add(intersectionPointResult.IntersectionPoints.First()); } } } IEnumerable <double> allXCoordinates = phreaticLineGeometry.Select(p => p.X) .Concat(waternetLineGeometry.Select(p => p.X)) .Concat(intersectionPoints.Select(p => p.X)) .OrderBy(d => d) .Distinct(); var waternetLineArea = new List <Point2D>(); var phreaticLineArea = new List <Point2D>(); var areaPoints = new List <Point2D>(); foreach (double xCoordinate in allXCoordinates) { IEnumerable <Point2D> phreaticLineIntersections = Math2D.SegmentsIntersectionWithVerticalLine(phreaticLineSegments, xCoordinate); IEnumerable <Point2D> waternetLineIntersections = Math2D.SegmentsIntersectionWithVerticalLine(waternetLineSegments, xCoordinate); if (!phreaticLineIntersections.Any() || !waternetLineIntersections.Any()) { continue; } Point2D phreaticLineIntersection = phreaticLineIntersections.First(); Point2D waternetLineIntersection = waternetLineIntersections.First(); waternetLineArea.Add(new Point2D(xCoordinate, waternetLineIntersection.Y)); phreaticLineArea.Add(new Point2D(xCoordinate, phreaticLineIntersection.Y)); if (intersectionPoints.Any(p => Math.Abs(p.X - xCoordinate) < tolerance)) { areaPoints.AddRange(phreaticLineArea); areaPoints.AddRange(waternetLineArea.OrderByDescending(p => p.X)); areaPoints.Add(phreaticLineArea.First()); areas.Add(areaPoints.ToArray()); waternetLineArea.Clear(); phreaticLineArea.Clear(); areaPoints.Clear(); waternetLineArea.Add(new Point2D(xCoordinate, waternetLineIntersection.Y)); phreaticLineArea.Add(new Point2D(xCoordinate, phreaticLineIntersection.Y)); } } areaPoints.AddRange(phreaticLineArea); areaPoints.AddRange(waternetLineArea.OrderByDescending(p => p.X)); areaPoints.Add(phreaticLineArea.First()); areas.Add(areaPoints.ToArray()); return(areas); }
private static IEnumerable <Point2D> ClipWaternetZoneToSurfaceLine(IEnumerable <Point2D> surfaceLineLocalGeometry, IEnumerable <Point2D> waternetZoneAsPolygon) { double leftX = Math.Max(waternetZoneAsPolygon.Min(p => p.X), surfaceLineLocalGeometry.Select(p => p.X).Min()); double rightX = Math.Min(waternetZoneAsPolygon.Max(p => p.X), surfaceLineLocalGeometry.Select(p => p.X).Max()); Segment2D[] surfaceLineSegments = Math2D.ConvertPointsToLineSegments(surfaceLineLocalGeometry).ToArray(); Segment2D[] waternetZoneSegments = Math2D.ConvertPointsToLineSegments(waternetZoneAsPolygon).ToArray(); var intersectionPoints = new List <Point2D>(); foreach (Segment2D surfaceLineSegment in surfaceLineSegments) { foreach (Segment2D waternetZoneSegment in waternetZoneSegments) { Segment2DIntersectSegment2DResult intersectionPointResult = Math2D.GetIntersectionBetweenSegments(surfaceLineSegment, waternetZoneSegment); if (intersectionPointResult.IntersectionType == Intersection2DType.Intersects) { intersectionPoints.Add(intersectionPointResult.IntersectionPoints.First()); } } } IEnumerable <double> allXCoordinates = waternetZoneAsPolygon.Select(p => p.X) .Concat(surfaceLineLocalGeometry.Select(p => p.X)) .Concat(intersectionPoints.Select(p => p.X)) .Where(x => x >= leftX && x <= rightX) .OrderBy(d => d) .Distinct(); var topLine = new List <Point2D>(); var bottomLine = new List <Point2D>(); foreach (double xCoordinate in allXCoordinates) { Point2D surfaceLineIntersection = Math2D.SegmentsIntersectionWithVerticalLine(surfaceLineSegments, xCoordinate).First(); IEnumerable <Point2D> waternetZoneIntersection = Math2D.SegmentsIntersectionWithVerticalLine(waternetZoneSegments, xCoordinate).Distinct().ToArray(); if (waternetZoneIntersection.Any()) { double waternetZoneTop = waternetZoneIntersection.Max(p => p.Y); double waternetZoneBottom = waternetZoneIntersection.Min(p => p.Y); double waternetBottomDelta = waternetZoneBottom - surfaceLineIntersection.Y; double waternetTopDelta = waternetZoneTop - surfaceLineIntersection.Y; if ((Math.Abs(waternetBottomDelta) < tolerance || waternetBottomDelta > 0) && !intersectionPoints.Any(c => c.X.Equals(xCoordinate))) { continue; } IEnumerable <Point2D> waternetZonePoints = waternetZoneIntersection.OrderBy(p => p.Y); if (Math.Abs(waternetTopDelta) < tolerance || waternetTopDelta < 0) { bottomLine.Add(waternetZonePoints.First()); topLine.Add(waternetZonePoints.Last()); } else if (waternetTopDelta > 0 && waternetBottomDelta < -1.0 * tolerance) { bottomLine.Add(waternetZonePoints.First()); topLine.Add(surfaceLineIntersection); } else if (Math.Abs(waternetBottomDelta) < tolerance && waternetTopDelta > 0) { bottomLine.Add(surfaceLineIntersection); topLine.Add(surfaceLineIntersection); } } } var area = new List <Point2D>(); if (AreaIsNotFlatLine(topLine, bottomLine)) { area.AddRange(topLine); List <Point2D> sortedBottomLine = bottomLine.OrderByDescending(p => p.X).ToList(); if (sortedBottomLine.First().Equals(topLine.Last())) { sortedBottomLine.Remove(sortedBottomLine.First()); } area.AddRange(sortedBottomLine); if (topLine.Any() && !area.Last().Equals(topLine.First())) { area.Add(topLine.First()); } } return(area.Count > 2 ? area : Enumerable.Empty <Point2D>()); }