Index: src/Plugins/Wti/Wti.IO/Builders/SoilLayer2D.cs =================================================================== diff -u -rf97fbfa34ad013491cc6ec609a9ef097be6625b7 -r4f83a029b2b4967a5f9e91dcd2ce06ecbbd09ddb --- src/Plugins/Wti/Wti.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision f97fbfa34ad013491cc6ec609a9ef097be6625b7) +++ src/Plugins/Wti/Wti.IO/Builders/SoilLayer2D.cs (.../SoilLayer2D.cs) (revision 4f83a029b2b4967a5f9e91dcd2ce06ecbbd09ddb) @@ -47,26 +47,20 @@ if (outerLoopIntersectionHeights.Count > 0) { - Collection> outerLoopIntersectionHeightPairs = new Collection>(); - AddOrderedStartAndEndPairsIn1D(outerLoopIntersectionHeights, outerLoopIntersectionHeightPairs); - foreach (var heightPair in outerLoopIntersectionHeightPairs) - { - result.Add(new PipingSoilLayer(heightPair.Item2)); - } - bottom = outerLoopIntersectionHeightPairs[0].Item1; - IEnumerable> innerLoopsIntersectionHeights = InnerLoops.Select(loop => GetLoopIntersectionHeights(loop, atX)); IEnumerable> innerLoopIntersectionHeightPairs = GetOrderedStartAndEndPairsIn1D(innerLoopsIntersectionHeights).ToList(); + IEnumerable> outerLoopIntersectionHeightPairs = GetOrderedStartAndEndPairsIn1D(outerLoopIntersectionHeights).ToList(); - bottom = EnsureBottomOutsideInnerLoop(innerLoopIntersectionHeightPairs.ToList(), bottom); + var currentBottom = outerLoopIntersectionHeightPairs.First().Item1; + var heights = new List(); + heights.AddRange(innerLoopIntersectionHeightPairs.Where(p => p.Item1 >= currentBottom).Select(p => p.Item1)); + heights.AddRange(outerLoopIntersectionHeightPairs.Select(p => p.Item2)); - foreach (var heightPair in innerLoopIntersectionHeightPairs) + foreach (var height in heights.Where(height => !innerLoopIntersectionHeightPairs.Any(tuple => HeightInInnerLoop(tuple, height)))) { - if (heightPair.Item1 > bottom) - { - result.Add(new PipingSoilLayer(heightPair.Item1)); - } + result.Add(new PipingSoilLayer(height)); } + bottom = EnsureBottomOutsideInnerLoop(innerLoopIntersectionHeightPairs, currentBottom); } } return result; @@ -86,31 +80,40 @@ return newBottom; } - private bool BottomInInnerLoop(Tuple tuple, double bottom) + private bool HeightInInnerLoop(Tuple tuple, double height) { - return bottom < tuple.Item2 && bottom >= tuple.Item1; + return height <= tuple.Item2 && height > tuple.Item1; } + private bool BottomInInnerLoop(Tuple tuple, double height) + { + return height < tuple.Item2 && height >= tuple.Item1; + } + private IEnumerable> GetOrderedStartAndEndPairsIn1D(IEnumerable> innerLoopsIntersectionPoints) { Collection> result = new Collection>(); foreach (var innerLoopIntersectionPoints in innerLoopsIntersectionPoints) { - AddOrderedStartAndEndPairsIn1D(innerLoopIntersectionPoints, result); + foreach (var tuple in GetOrderedStartAndEndPairsIn1D(innerLoopIntersectionPoints)) + { + result.Add(tuple); + } } return result; } - private static void AddOrderedStartAndEndPairsIn1D(Collection innerLoopIntersectionPoints, Collection> result) + private static Collection> GetOrderedStartAndEndPairsIn1D(IEnumerable innerLoopIntersectionPoints) { + var result = new Collection>(); var orderedHeights = innerLoopIntersectionPoints.OrderBy(v => v).ToList(); - while (orderedHeights.Count >= 2) + for (int i = 0; i < orderedHeights.Count; i = i+2) { - var first = orderedHeights[0]; - var second = orderedHeights[1]; - orderedHeights.RemoveRange(0, 2); + var first = orderedHeights[i]; + var second = orderedHeights[i+1]; result.Add(new Tuple(first, second)); } + return result; } private Collection GetLoopIntersectionHeights(HashSet loop, double atX) Index: test/Plugins/Wti/Wti.IO.Test/Builders/SoilLayer2DTest.cs =================================================================== diff -u -r2423a70958e7fecfc92afa462c34194cc695a81e -r4f83a029b2b4967a5f9e91dcd2ce06ecbbd09ddb --- test/Plugins/Wti/Wti.IO.Test/Builders/SoilLayer2DTest.cs (.../SoilLayer2DTest.cs) (revision 2423a70958e7fecfc92afa462c34194cc695a81e) +++ test/Plugins/Wti/Wti.IO.Test/Builders/SoilLayer2DTest.cs (.../SoilLayer2DTest.cs) (revision 4f83a029b2b4967a5f9e91dcd2ce06ecbbd09ddb) @@ -309,27 +309,109 @@ var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, "6", "........", + "...12...", "........", + "...43...", + "........", + "........")); + + var innerLoop2 = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + "6", + "........", + "........", "...12...", "........", "........", "...43...")); - var innerLoop2 = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + var layer = new SoilLayer2D + { + OuterLoop = outerLoop, + InnerLoops = + { + innerLoop, + innerLoop2 + } + }; + + // Call + double bottom; + var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray(); + + // Assert + Assert.AreEqual(1, result.Length); + Assert.AreEqual(4.0, bottom); + CollectionAssert.AreEquivalent(new[] { 5.0 }, result.Select(rl => rl.Top)); + } + + [Test] + public void AsPipingSoilLayers_OuterLoopInnerLoopOnBorderBottom_ReturnsTwoLayers() + { + // Setup + var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, "6", + "..1..2..", "........", + "........", + "........", + ".4....3.", + "........")); + + var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + "6", + "........", + "........", "...12...", "........", "...43...", + "........")); + + var layer = new SoilLayer2D + { + OuterLoop = outerLoop, + InnerLoops = + { + innerLoop + } + }; + + // Call + double bottom; + var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray(); + + // Assert + Assert.AreEqual(2, result.Length); + Assert.AreEqual(3.0, bottom); + CollectionAssert.AreEquivalent(new[] { 5.0, 1.0 }, result.Select(rl => rl.Top)); + } + + [Test] + public void AsPipingSoilLayers_OuterLoopInnerLoopOverlapTop_ReturnsOneLayer() + { + // Setup + var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + "6", "........", + "..1..2..", + "........", + "........", + ".4....3.", "........")); + var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + "6", + "...43...", + "........", + "...12...", + "........", + "........", + "........")); + var layer = new SoilLayer2D { OuterLoop = outerLoop, InnerLoops = { - innerLoop2, innerLoop } }; @@ -340,11 +422,52 @@ // Assert Assert.AreEqual(1, result.Length); - Assert.AreEqual(4.0, bottom); - CollectionAssert.AreEquivalent(new[] { 5.0 }, result.Select(rl => rl.Top)); + Assert.AreEqual(1.0, bottom); + CollectionAssert.AreEquivalent(new[] { 3.0 }, result.Select(rl => rl.Top)); } [Test] + public void AsPipingSoilLayers_OuterLoopInnerLoopOnBorderTop_ReturnsOneLayer() + { + // Setup + var outerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + "6", + "..1..2..", + "........", + "........", + "........", + ".4....3.", + "........")); + + var innerLoop = PointCollectionHelper.CreateFromString(String.Join(Environment.NewLine, + "6", + "...43...", + "........", + "...12...", + "........", + "........", + "........")); + + var layer = new SoilLayer2D + { + OuterLoop = outerLoop, + InnerLoops = + { + innerLoop + } + }; + + // Call + double bottom; + var result = layer.AsPipingSoilLayers(3.5, out bottom).ToArray(); + + // Assert + Assert.AreEqual(1, result.Length); + Assert.AreEqual(1.0, bottom); + CollectionAssert.AreEquivalent(new[] { 3.0 }, result.Select(rl => rl.Top)); + } + + [Test] public void AsPipingSoilLayers_OuterLoopVerticalAtX_ThrowsException() { // Setup