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());
        }
 private static bool DoesSegmentIntersectWithSegmentArray(Segment2D segment, Segment2D[] segmentArray)
 {
     // Consider intersections and overlaps similarly
     return(segmentArray.Any(sls => Math2D.GetIntersectionBetweenSegments(segment, sls).IntersectionType != Intersection2DType.DoesNotIntersect));
 }
Exemple #3
0
        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);
        }
Exemple #4
0
        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>());
        }