// Copyright (C) Stichting Deltares 2024. All rights reserved.
//
// This file is part of the Dam Engine.
//
// The Dam Engine is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System.Collections.Generic;
using System.Linq;
using Deltares.DamEngine.Data.Geometry;
using NUnit.Framework;
namespace Deltares.DamEngine.Data.Tests.General;
[TestFixture]
public class GeometryDataTests
{
[Test]
public void TestRemoveDoublesFromNewlyEffectedPointsAndCurves()
{
var point1 = new Point2D(1, 0); // to be kept
var point2 = new Point2D(1, 0); // to be removed as == p1
var point3 = new Point2D(5, 0); // to be kept
var point4 = new Point2D(5, 0); // to be removed as == p3
var point5 = new Point2D(1, 0); // to be removed as == p1
var point6 = new Point2D(5, 0); // to be removed as == p3
var curve1 = new GeometryCurve(point1, point2); // to be removed as no lenght
var curve2 = new GeometryCurve(point2, point3); // to be kept
var curve3 = new GeometryCurve(point1, point2); // to be removed as no lenght
var curve4 = new GeometryCurve(point4, point1); // to be removed as == c2 (in reverse order)
var curve5 = new GeometryCurve(point3, point5); // to be removed as == c2 (in reverse order)
var curve6 = new GeometryCurve(point1, point1); // to be removed as no lenght
var curve7 = new GeometryCurve(point1, point1); // to be removed as no lenght
var curve8 = new GeometryCurve(null, null); // to be removed as no points
var curve9 = new GeometryCurve(null, point2); // to be removed as no headpoint
var curve10 = new GeometryCurve(point3, null); // to be removed as no endpoint
var geometrymodel = new GeometryData();
geometrymodel.NewlyEffectedPoints.Add(point1);
geometrymodel.NewlyEffectedPoints.Add(point2);
geometrymodel.NewlyEffectedPoints.Add(point3);
geometrymodel.NewlyEffectedPoints.Add(point4);
geometrymodel.NewlyEffectedPoints.Add(point5);
geometrymodel.NewlyEffectedPoints.Add(point6);
geometrymodel.NewlyEffectedCurves.Add(curve1);
geometrymodel.NewlyEffectedCurves.Add(curve2);
geometrymodel.NewlyEffectedCurves.Add(curve3);
geometrymodel.NewlyEffectedCurves.Add(curve4);
geometrymodel.NewlyEffectedCurves.Add(curve5);
geometrymodel.NewlyEffectedCurves.Add(curve6);
geometrymodel.NewlyEffectedCurves.Add(curve7);
geometrymodel.NewlyEffectedCurves.Add(curve8);
geometrymodel.NewlyEffectedCurves.Add(curve9);
geometrymodel.NewlyEffectedCurves.Add(curve10);
geometrymodel.RemoveDoublesFromNewlyEffectedPointsAndCurves();
// only two points are unique by location
Assert.That(geometrymodel.NewlyEffectedPoints.Count, Is.EqualTo(2));
// only two curves hold both head and endpoint with unique locations
Assert.That(geometrymodel.NewlyEffectedCurves.Count, Is.EqualTo(1));
}
[Test]
public void GeometryHelperTestSurfaceTwoVertLayers()
{
GeometryData gData = CreateGeometrySurface2();
GeometryPointString line = gData.SurfaceLine;
Assert.That(line.Points.Count, Is.EqualTo(3));
Assert.That(line.Points.OrderBy(p => p.X).First().X, Is.EqualTo(1.0));
Assert.That(line.Points.OrderByDescending(p => p.X).First().X, Is.EqualTo(10.0));
}
[Test]
public void GeometryDataTestSurfaceTwoHorLayers()
{
GeometryData gData = CreateGeometrySurface();
GeometryPointString line = gData.SurfaceLine;
Assert.That(line.CalcPoints.Count, Is.EqualTo(2));
Assert.That(line.CalcPoints.OrderBy(p => p.X).First().X, Is.EqualTo(1.0));
Assert.That(line.CalcPoints.OrderByDescending(p => p.X).First().X, Is.EqualTo(10.0));
}
[Test]
public void TestSimpleGeneration()
{
var geom = new GeometryData
{
Left = 0,
Bottom = 0,
Right = 100
};
var p1 = new Point2D(0, 5);
geom.NewlyEffectedPoints.Add(p1);
var p2 = new Point2D(100, 5);
geom.NewlyEffectedPoints.Add(p2);
var p3 = new Point2D(0, 0);
geom.NewlyEffectedPoints.Add(p3);
var p4 = new Point2D(100, 0);
geom.NewlyEffectedPoints.Add(p4);
geom.NewlyEffectedCurves.Add(new GeometryCurve(p1, p2));
geom.NewlyEffectedCurves.Add(new GeometryCurve(p3, p4));
geom.NewlyEffectedCurves.Add(new GeometryCurve(p1, p3));
geom.NewlyEffectedCurves.Add(new GeometryCurve(p2, p4));
geom.RegenerateGeometry();
Assert.That(geom.Points.Count, Is.EqualTo(4));
Assert.That(geom.Curves.Count, Is.EqualTo(4));
Assert.That(geom.Surfaces.Count, Is.EqualTo(1));
Assert.That(geom.Surfaces[0].InnerLoops.Count, Is.EqualTo(0));
Assert.That(geom.Surfaces[0].OuterLoop.Count, Is.EqualTo(4));
Assert.That(geom.Surfaces[0].OuterLoop.CurveList.Count, Is.EqualTo(4));
Assert.That(geom.Surfaces[0].OuterLoop.Points.Count, Is.EqualTo(4));
Assert.That(geom.Surfaces[0].OuterLoop.HasArea(), Is.True);
Assert.That(geom.Surfaces[0].OuterLoop.IsLoop(), Is.True);
Assert.That(geom.Surfaces[0].OuterLoop.IsPointInLoopArea(new Point2D(25, 3)), Is.True);
Assert.That(geom.Surfaces[0].OuterLoop.IsPointInLoopArea(new Point2D(25, 5.1)), Is.False);
}
[Test]
[TestCase(1, 0, true)]
[TestCase(10, 0, true)]
[TestCase(10, 10, true)]
[TestCase(1, 10, true)]
[TestCase(1, 1, false)]
[TestCase(0, 1, false)]
public void GivenPointsWhenGetPointAtLocationCalledThenCorrectPointIsReturned(double x, double z, bool isPresent)
{
const double tolerance = 1e-6;
var geometryModel = new GeometryData();
var point1 = new Point2D(1, 0);
var point2 = new Point2D(10, 0);
var point3 = new Point2D(10, 10);
var point4 = new Point2D(1, 10);
geometryModel.Points.AddRange(new[]
{
point1,
point2,
point3,
point4
});
Point2D point = geometryModel.GetPointAtLocation(new Point2D(x, z), tolerance);
if (isPresent)
{
Assert.That(point, Is.Not.Null);
Assert.That(point.X, Is.EqualTo(x).Within(tolerance));
Assert.That(point.Z, Is.EqualTo(z).Within(tolerance));
}
else
{
Assert.That(point, Is.Null);
}
}
[Test]
[TestCase(0, 0, 3, 0, 2, 4)]
[TestCase(0, 10, 3, 2, 3, 5)]
[TestCase(10, 10, 3, 1, 2, 4)]
[TestCase(10, 0, 3, 0, 1, 5)]
[TestCase(5, 5, 2, 4, 5, -1)]
[TestCase(1, 1, 1, 4, -1, -1)]
[TestCase(9, 1, 1, 5, -1, -1)]
[TestCase(1, 3, 0, -1, -1, -1)]
public void GivenPointsWhenGetCurvesCoincidingWithPointCalledThenCorrectCurvesAreReturned(double x, double z, int curveCount, int curve1, int curve2, int curve3)
{
var geometryModel = new GeometryData();
// The following model looks as follows
// _______
// |\ /|
// | \ / |
// | X |
// | / \ |
// |/___\|
geometryModel.Curves.AddRange(new[]
{
new GeometryCurve(new Point2D(0, 0), new Point2D(10, 0)), // index 0
new GeometryCurve(new Point2D(10, 0), new Point2D(10, 10)), // index 1
new GeometryCurve(new Point2D(10, 10), new Point2D(0, 10)), // index 2
new GeometryCurve(new Point2D(0, 10), new Point2D(0, 0)), // index 3
new GeometryCurve(new Point2D(0, 0), new Point2D(10, 10)), // index 4
new GeometryCurve(new Point2D(10, 0), new Point2D(0, 10)) // index 5
});
var curveList = new List();
geometryModel.GetCurvesCoincidingWithPoint(new Point2D(x, z), ref curveList);
Assert.That(curveList.Count, Is.EqualTo(curveCount));
if (curveCount > 0 && curve1 >= 0)
{
Assert.That(curveList[0].Equals(geometryModel.Curves[curve1]), Is.True);
}
}
private GeometryData CreateGeometrySurface()
{
var geometryModel = new GeometryData();
/* The following model looks as follows
*
* |----------|
* | |
* |----------|
* | |
* |----------|
*
*/
var point1 = new Point2D(1, 0);
var point2 = new Point2D(10, 0);
var point3 = new Point2D(10, 10);
var point4 = new Point2D(1, 10);
var point5 = new Point2D(1, 5);
var point6 = new Point2D(10, 5);
var curve1 = new GeometryCurve(point1, point2);
var curve2 = new GeometryCurve(point2, point3);
var curve3 = new GeometryCurve(point3, point4);
var curve4 = new GeometryCurve(point4, point1);
var curve5 = new GeometryCurve(point5, point6);
geometryModel.Points.AddRange(new[]
{
point1,
point2,
point3,
point4,
point5,
point6
});
geometryModel.Curves.AddRange(new[]
{
curve1,
curve2,
curve3,
curve4,
curve5
});
geometryModel.NewlyEffectedPoints.AddRange(geometryModel.Points);
geometryModel.NewlyEffectedCurves.AddRange(geometryModel.Curves);
geometryModel.RegenerateGeometry();
return geometryModel;
}
private GeometryData CreateGeometrySurface2()
{
var geometryModel = new GeometryData();
/* The following model looks as follows
*
* |-----|----|
* | | |
* | | |
* | | |
* |-----|----|
*
*/
var point1 = new Point2D(1, 0);
var point2 = new Point2D(1, 10);
var point3 = new Point2D(5, 10);
var point4 = new Point2D(5, 0);
var point5 = new Point2D(10, 10);
var point6 = new Point2D(10, 0);
var curve1 = new GeometryCurve(point1, point2);
var curve2 = new GeometryCurve(point2, point3);
var curve3 = new GeometryCurve(point3, point4);
var curve4 = new GeometryCurve(point4, point1);
var curve5 = new GeometryCurve(point3, point5);
var curve6 = new GeometryCurve(point5, point6);
var curve7 = new GeometryCurve(point6, point4);
geometryModel.Points.AddRange(new[]
{
point1,
point2,
point3,
point4,
point5,
point6
});
geometryModel.Curves.AddRange(new[]
{
curve1,
curve2,
curve3,
curve4,
curve5,
curve5,
curve6,
curve7
});
geometryModel.NewlyEffectedPoints.AddRange(geometryModel.Points);
geometryModel.NewlyEffectedCurves.AddRange(geometryModel.Curves);
geometryModel.RegenerateGeometry();
return geometryModel;
}
private GeometryData CreateDonutGeometry()
{
var geometryModel = new GeometryData
{
Left = -10,
Bottom = -10,
Right = 20
};
/* The following model looks as follows
*
* |----------|
* | ------ |
* | | | |
* | | | |
* | ------ |
* |----------|
*
*/
var point1 = new Point2D(0, 0);
var point2 = new Point2D(0, 10);
var point3 = new Point2D(10, 10);
var point4 = new Point2D(10, 0);
var point5 = new Point2D(3, 3);
var point6 = new Point2D(3, 7);
var point7 = new Point2D(7, 7);
var point8 = new Point2D(7, 3);
var curve1 = new GeometryCurve(point1, point2);
var curve2 = new GeometryCurve(point2, point3);
var curve3 = new GeometryCurve(point3, point4);
var curve4 = new GeometryCurve(point4, point1);
var curve5 = new GeometryCurve(point5, point6);
var curve6 = new GeometryCurve(point6, point7);
var curve7 = new GeometryCurve(point7, point8);
var curve8 = new GeometryCurve(point8, point5);
geometryModel.Points.AddRange(new[]
{
point1,
point2,
point3,
point4,
point5,
point6,
point7,
point8
});
geometryModel.Curves.AddRange(new[]
{
curve1,
curve2,
curve3,
curve4,
curve5,
curve5,
curve6,
curve7,
curve8
});
geometryModel.NewlyEffectedPoints.AddRange(geometryModel.Points);
geometryModel.NewlyEffectedCurves.AddRange(geometryModel.Curves);
geometryModel.RegenerateGeometry();
return geometryModel;
}
}