Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs =================================================================== diff -u -r3270 -r3271 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (.../SoilSurfaceProfile.cs) (revision 3270) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SoilSurfaceProfile.cs (.../SoilSurfaceProfile.cs) (revision 3271) @@ -380,45 +380,54 @@ return Enumerable.Empty(); } - double layerTopLevel = soilLayer.TopLevel; - double layerBottomLevel = soilLayer.BottomLevel; + var enclosedAreas = GetEnclosedAreas(pointsArray, soilLayer.TopLevel, soilLayer.BottomLevel); + return enclosedAreas.Select(a => CreateLayerData(a, soilLayer)).ToArray(); + } - // Determine the points that are part of the geometry + /// + /// Determines the enclosed areas that are formed by the intersections between the surface line, the top level and the bottom level. + /// + /// The collection of that define the surface line. + /// The top level. + /// The bottom level. + /// A collection of . + private static IEnumerable GetEnclosedAreas(IReadOnlyList surfaceLinePoints, double topLevel, double bottomLevel) + { var currentArea = new EnclosedArea(); var enclosedAreas = new List(); - - double previousZCoordinate = pointsArray[0].Z; + + double previousZCoordinate = surfaceLinePoints[0].Z; int j = 1; - for (int i = 0; i < pointsArray.Length; i++) + for (int i = 0; i < surfaceLinePoints.Count; i++) { - Point2D currentPoint = pointsArray[i]; + Point2D currentPoint = surfaceLinePoints[i]; double xCoordinate = currentPoint.X; double zCoordinateSurfaceLine = currentPoint.Z; - double nextSurfaceLineZCoordinate = pointsArray[j].Z; + double nextSurfaceLineZCoordinate = surfaceLinePoints[j].Z; double currentZCoordinate = zCoordinateSurfaceLine; - if (zCoordinateSurfaceLine > layerTopLevel) + if (zCoordinateSurfaceLine > topLevel) { - currentZCoordinate = layerTopLevel; - currentArea.AddCoordinate(new Point2D(xCoordinate, layerTopLevel)); + currentZCoordinate = topLevel; + currentArea.AddCoordinate(new Point2D(xCoordinate, topLevel)); } - else if (Math.Abs(zCoordinateSurfaceLine - layerBottomLevel) < GeometryConstants.Accuracy // Surface line is at layer bottom level - || (zCoordinateSurfaceLine >= layerBottomLevel && zCoordinateSurfaceLine <= layerTopLevel)) // Surface line is between the layer top and bottom level + else if (Math.Abs(zCoordinateSurfaceLine - bottomLevel) < GeometryConstants.Accuracy // Surface line is at layer bottom level + || (zCoordinateSurfaceLine >= bottomLevel && zCoordinateSurfaceLine <= topLevel)) // Surface line is between the layer top and bottom level { currentArea.AddCoordinate(new Point2D(xCoordinate, zCoordinateSurfaceLine)); } // Determine if the current surface line point is located as a point on the horizontal line on the layer bottom level. // If yes, then a new area should be added - if (Math.Abs(zCoordinateSurfaceLine - layerBottomLevel) < GeometryConstants.Accuracy - && Math.Abs(nextSurfaceLineZCoordinate - layerBottomLevel) < GeometryConstants.Accuracy) + if (Math.Abs(zCoordinateSurfaceLine - bottomLevel) < GeometryConstants.Accuracy + && Math.Abs(nextSurfaceLineZCoordinate - bottomLevel) < GeometryConstants.Accuracy) { enclosedAreas.Add(currentArea); currentArea = new EnclosedArea(); } - else if (previousZCoordinate > layerBottomLevel // Area should also be added when the area already started above or at the soil layer bottom - && zCoordinateSurfaceLine < previousZCoordinate // The surface line has a decreasing trend w.r.t. the previous z coordinate - && zCoordinateSurfaceLine <= layerBottomLevel) // The surface line crossed the bottom of the layer + else if (previousZCoordinate > bottomLevel // Area should also be added when the area already started above or at the soil layer bottom + && zCoordinateSurfaceLine < previousZCoordinate // The surface line has a decreasing trend w.r.t. the previous z coordinate + && zCoordinateSurfaceLine <= bottomLevel) // The surface line crossed the bottom of the layer { enclosedAreas.Add(currentArea); currentArea = new EnclosedArea(); @@ -435,15 +444,14 @@ previousZCoordinate = currentZCoordinate; // End of array, take the last Z coordinate as the next coordinate - j = i == pointsArray.Length - 2 ? j : j + 1; + j = i == surfaceLinePoints.Count - 2 ? j : j + 1; } // The last area needs to be added manually enclosedAreas.Add(currentArea); - - return enclosedAreas.Where(area => area.Coordinates.Count() > 1) - .Select(a => CreateLayerData(a, soilLayer)) - .ToArray(); + + // Filter the areas that contain more than 1 coordinate + return enclosedAreas.Where(area => area.Coordinates.Count() > 1); } private static LayerData CreateLayerData(EnclosedArea area, SoilLayer1D soilLayer)