Add more tests.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Meshing;
|
||||
|
||||
namespace TriangleNet.Tests.Meshing
|
||||
{
|
||||
public class GenericMesherTest
|
||||
{
|
||||
[Test]
|
||||
public void TestTriangulateDwyer()
|
||||
{
|
||||
var m = new GenericMesher();
|
||||
|
||||
var vertices = GetVertices();
|
||||
|
||||
var mesh = m.Triangulate(vertices);
|
||||
|
||||
Assert.AreEqual(6, vertices.Count);
|
||||
Assert.AreEqual(6, mesh.Vertices.Count);
|
||||
Assert.AreEqual(1, mesh.Vertices
|
||||
.Where(v => v.Type == VertexType.UndeadVertex)
|
||||
.Count());
|
||||
}
|
||||
|
||||
private List<Vertex> GetVertices()
|
||||
{
|
||||
return new List<Vertex>()
|
||||
{
|
||||
new Vertex(0.0, 0.0),
|
||||
new Vertex(1.0, 0.0),
|
||||
new Vertex(1.0, 1.0),
|
||||
new Vertex(1.0, 1.0), // duplicate
|
||||
new Vertex(0.0, 1.0),
|
||||
new Vertex(0.5, 0.5)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.IO;
|
||||
using TriangleNet.Meshing;
|
||||
using TriangleNet.Meshing.Iterators;
|
||||
|
||||
namespace TriangleNet.Tests.Meshing.Iterators
|
||||
{
|
||||
public class VertexCirculatorTest
|
||||
{
|
||||
[Test]
|
||||
public void TestEnumerateVertices()
|
||||
{
|
||||
// 5
|
||||
// /\
|
||||
// / \
|
||||
// / \
|
||||
// 3/______\4
|
||||
// /\ /\
|
||||
// / \ / \
|
||||
// / \ / \
|
||||
// 0/______\/______\2
|
||||
// 1
|
||||
|
||||
var mesh = CreateMesh(out var vertices);
|
||||
|
||||
var circulator = new VertexCirculator(mesh);
|
||||
|
||||
var p = vertices[0];
|
||||
|
||||
var list = circulator.EnumerateVertices(p).ToList();
|
||||
|
||||
Assert.AreEqual(2, list.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEnumerateTriangles()
|
||||
{
|
||||
var mesh = CreateMesh(out var vertices);
|
||||
|
||||
var circulator = new VertexCirculator(mesh);
|
||||
|
||||
var p = vertices[0];
|
||||
|
||||
var list = circulator.EnumerateTriangles(p).ToList();
|
||||
|
||||
Assert.AreEqual(1, list.Count);
|
||||
}
|
||||
|
||||
private Mesh CreateMesh(out Vertex[] vertices)
|
||||
{
|
||||
var poly = new Polygon();
|
||||
|
||||
vertices = new Vertex[]
|
||||
{
|
||||
new Vertex(-2.0, 0.0, 0),
|
||||
new Vertex(0.0, 0.0, 1),
|
||||
new Vertex(2.0, 0.0, 2),
|
||||
new Vertex(-1.0, 1.0, 3),
|
||||
new Vertex(1.0, 1.0, 4),
|
||||
new Vertex(0.0, 2.0, 5)
|
||||
};
|
||||
|
||||
poly.Points.AddRange(vertices);
|
||||
|
||||
var triangles = new InputTriangle[]
|
||||
{
|
||||
new InputTriangle(3, 0, 1) { ID = 1 },
|
||||
new InputTriangle(3, 1, 4) { ID = 2 },
|
||||
new InputTriangle(4, 1, 2) { ID = 3 },
|
||||
new InputTriangle(5, 3, 4) { ID = 4 },
|
||||
};
|
||||
|
||||
return Converter.Instance.ToMesh(poly, triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Meshing;
|
||||
using TriangleNet.Tools;
|
||||
|
||||
namespace TriangleNet.Tests.Tools
|
||||
{
|
||||
public class AdjacencyMatrixTest
|
||||
{
|
||||
[Test]
|
||||
public void TestAdjacencyMatrix()
|
||||
{
|
||||
var p = GetVertices(false);
|
||||
var mesher = new GenericMesher();
|
||||
var mesh = (Mesh)mesher.Triangulate(p);
|
||||
|
||||
Assert.AreEqual(5, mesh.Vertices.Max(v => v.ID));
|
||||
|
||||
mesh.Renumber();
|
||||
|
||||
var matrix = new AdjacencyMatrix(mesh);
|
||||
|
||||
// Highest vertex id after renumbering is 4, since there
|
||||
// is no duplicate vertex.
|
||||
Assert.AreEqual(4, matrix.RowIndices.Max());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAdjacencyMatrixDuplicate()
|
||||
{
|
||||
var p = GetVertices(true);
|
||||
var mesher = new GenericMesher();
|
||||
var mesh = (Mesh)mesher.Triangulate(p);
|
||||
|
||||
mesh.Renumber();
|
||||
|
||||
var matrix = new AdjacencyMatrix(mesh);
|
||||
|
||||
var ai = matrix.RowIndices;
|
||||
|
||||
// Highest vertex id after renumbering is 5, since the duplicate
|
||||
// vertex is still present in the mesh vertices list.
|
||||
Assert.AreEqual(5, ai.Max());
|
||||
|
||||
// Get the single, duplicate vertex.
|
||||
var dup = mesh.Vertices
|
||||
.Where(v => v.Type == VertexType.UndeadVertex)
|
||||
.Single();
|
||||
|
||||
// The duplicate vertex is part of the matrix, since it is assumed
|
||||
// to be adjacent to itself.
|
||||
Assert.AreEqual(1, ai.Count(i => i == dup.id));
|
||||
|
||||
// TODO: fix AdjacencyMatrix!!!
|
||||
}
|
||||
|
||||
private List<Vertex> GetVertices(bool includeDuplicate)
|
||||
{
|
||||
var list = new List<Vertex>()
|
||||
{
|
||||
new Vertex(0.0, 0.0) { ID = 5 },
|
||||
new Vertex(1.0, 0.0) { ID = 4 },
|
||||
new Vertex(1.0, 1.0) { ID = 3 }
|
||||
};
|
||||
|
||||
if (includeDuplicate)
|
||||
{
|
||||
list.Add(new Vertex(1.0, 1.0) { ID = 2 });
|
||||
}
|
||||
|
||||
list.Add(new Vertex(0.0, 1.0) { ID = 1 });
|
||||
list.Add(new Vertex(0.5, 0.5) { ID = 0 });
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Tools;
|
||||
|
||||
@@ -6,6 +7,139 @@ namespace TriangleNet.Tests.Tools
|
||||
{
|
||||
public class IntersectionHelperTest
|
||||
{
|
||||
private const double EPS = 1e-8;
|
||||
|
||||
Rectangle box;
|
||||
Point p;
|
||||
|
||||
[SetUp]
|
||||
public void Initialize()
|
||||
{
|
||||
// Square centered at origin.
|
||||
box = new Rectangle(-1.0, -1.0, 2.0, 2.0);
|
||||
|
||||
// Starting point of ray for box-ray intersection.
|
||||
p = new Point(0.0, 0.0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBoxRayIntersectionCorners()
|
||||
{
|
||||
var c = new Point(0.0, 0.0);
|
||||
|
||||
var check = (Point c, double x, double y) => Math.Abs(c.X - x) < EPS && Math.Abs(c.Y - y) < EPS;
|
||||
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.2, -0.2, ref c);
|
||||
Assert.IsTrue(check(c, -1.0, -1.0));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.2, -0.2, ref c);
|
||||
Assert.IsTrue(check(c, 1.0, -1.0));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.2, 0.2, ref c);
|
||||
Assert.IsTrue(check(c, 1.0, 1.0));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.2, 0.2, ref c);
|
||||
Assert.IsTrue(check(c, -1.0, 1.0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBoxRayIntersectionHorizontalVertical()
|
||||
{
|
||||
var a = new Point(0.0, 0.0);
|
||||
|
||||
var check = (Point c, double x, double y) => Math.Abs(c.X - x) < EPS && Math.Abs(c.Y - y) < EPS;
|
||||
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.2, 0.0, ref a);
|
||||
Assert.IsTrue(check(a, -1.0, 0.0));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.2, 0.0, ref a);
|
||||
Assert.IsTrue(check(a, 1.0, 0.0));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.0, -0.2, ref a);
|
||||
Assert.IsTrue(check(a, 0.0, -1.0));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.0, 0.2, ref a);
|
||||
Assert.IsTrue(check(a, 0.0, 1.0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBoxRayIntersectionBottom()
|
||||
{
|
||||
var a = new Point(0.0, 0.0);
|
||||
|
||||
var check = (Point c, Rectangle r) => Math.Abs(c.Y - r.Bottom) < EPS && c.X > r.Left - EPS && c.X < r.Right + EPS;
|
||||
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.4, -0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.2, -0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.1, -0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.1, -0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.2, -0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.4, -0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBoxRayIntersectionTop()
|
||||
{
|
||||
var a = new Point(0.0, 0.0);
|
||||
|
||||
var check = (Point c, Rectangle r) => Math.Abs(c.Y - r.Top) < EPS && c.X > r.Left - EPS && c.X < r.Right + EPS;
|
||||
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.4, 0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.2, 0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.1, 0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.1, 0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.2, 0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.4, 0.5, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBoxRayIntersectionLeft()
|
||||
{
|
||||
var a = new Point(0.0, 0.0);
|
||||
|
||||
var check = (Point c, Rectangle r) => Math.Abs(c.X - r.Left) < EPS && c.Y > r.Bottom - EPS && c.Y < r.Top + EPS;
|
||||
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.5, -0.4, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.5, -0.2, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.5, -0.1, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.5, 0.1, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.5, 0.2, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, -0.5, 0.4, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBoxRayIntersectionRight()
|
||||
{
|
||||
var a = new Point(0.0, 0.0);
|
||||
|
||||
var check = (Point c, Rectangle r) => Math.Abs(c.X - r.Right) < EPS && c.Y > r.Bottom - EPS && c.Y < r.Top + EPS;
|
||||
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.5, -0.4, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.5, -0.2, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.5, -0.1, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.5, 0.1, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.5, 0.2, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
IntersectionHelper.BoxRayIntersection(box, p, 0.5, 0.4, ref a);
|
||||
Assert.IsTrue(check(a, box));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsPointOnSegment()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Tools;
|
||||
|
||||
namespace TriangleNet.Tests.Tools
|
||||
{
|
||||
public class StatisticTest
|
||||
{
|
||||
[Test, DefaultFloatingPointTolerance(1e-1)]
|
||||
public void TestComputeAngles()
|
||||
{
|
||||
// Angles: 90, 45, 45
|
||||
var t = Helper.CreateTriangle(1 ,new Vertex(0.0, 0.0), new Vertex(1.0, 0.0), new Vertex(0.0, 1.0));
|
||||
var a = ComputeAngles(t);
|
||||
|
||||
Assert.AreEqual(45.0, a.min);
|
||||
Assert.AreEqual(90.0, a.max);
|
||||
|
||||
// Angles: 135, 14, 31
|
||||
t = Helper.CreateTriangle(1 ,new Vertex(0.0, 0.0), new Vertex(3.0, 0.0), new Vertex(-1.0, 1.0));
|
||||
a = ComputeAngles(t);
|
||||
|
||||
Assert.AreEqual(14.0, a.min);
|
||||
Assert.AreEqual(135.0, a.max);
|
||||
|
||||
// Angles: 60, 60, 60
|
||||
t = Helper.CreateTriangle(1 ,new Vertex(0.0, 0.0), new Vertex(2.0, 0.0), new Vertex(1.0, 1.73));
|
||||
a = ComputeAngles(t);
|
||||
|
||||
Assert.AreEqual(60.0, a.min);
|
||||
Assert.AreEqual(60.0, a.max);
|
||||
|
||||
// Angles: 180
|
||||
t = Helper.CreateTriangle(1 ,new Vertex(0.0, 0.0), new Vertex(10000.0, 1.0), new Vertex(-10000.0, 1.0));
|
||||
a = ComputeAngles(t);
|
||||
|
||||
Assert.AreEqual(0.0, a.min);
|
||||
Assert.AreEqual(180.0, a.max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the minimum and maximum angle of given triangle (in degrees).
|
||||
/// </summary>
|
||||
private (double min, double max) ComputeAngles(ITriangle triangle)
|
||||
{
|
||||
var data = new double[6];
|
||||
|
||||
Statistic.ComputeAngles(triangle, data);
|
||||
|
||||
bool acute = data[2] > 0;
|
||||
|
||||
double min = Math.Acos(Math.Sqrt(data[0]));
|
||||
double max = Math.Acos(Math.Sqrt(data[1]));
|
||||
|
||||
const double deg = 180.0 / Math.PI;
|
||||
|
||||
return (deg * min, acute ? deg * max : deg * (Math.PI - max));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
|
||||
namespace TriangleNet.Tests
|
||||
{
|
||||
class TrianglePoolTest
|
||||
{
|
||||
[Test]
|
||||
public void TestGetRelease()
|
||||
{
|
||||
var pool = new TrianglePool();
|
||||
|
||||
var t0 = pool.Get();
|
||||
var t1 = pool.Get();
|
||||
var t2 = pool.Get();
|
||||
|
||||
Assert.AreEqual(0, t0.ID);
|
||||
Assert.AreEqual(1, t1.ID);
|
||||
Assert.AreEqual(2, t2.ID);
|
||||
|
||||
Assert.AreEqual(3, pool.Count);
|
||||
|
||||
pool.Release(t0);
|
||||
|
||||
Assert.AreEqual(2, pool.Count);
|
||||
Assert.Less(t0.GetHashCode(), 0);
|
||||
|
||||
pool.Release(t1);
|
||||
|
||||
Assert.AreEqual(1, pool.Count);
|
||||
Assert.Less(t1.GetHashCode(), 0);
|
||||
|
||||
var t4 = pool.Get();
|
||||
|
||||
Assert.AreEqual(2, pool.Count);
|
||||
Assert.AreEqual(t1.ID, t4.ID);
|
||||
|
||||
var t5 = pool.Get();
|
||||
|
||||
Assert.AreEqual(3, pool.Count);
|
||||
Assert.AreEqual(t0.ID, t5.ID);
|
||||
|
||||
var t6 = pool.Get();
|
||||
|
||||
Assert.AreEqual(4, pool.Count);
|
||||
Assert.AreEqual(3, t6.ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestToArray()
|
||||
{
|
||||
var pool = new TrianglePool();
|
||||
|
||||
// Create 4 triangles.
|
||||
pool.Get();
|
||||
pool.Get();
|
||||
pool.Get();
|
||||
pool.Get();
|
||||
|
||||
var a = pool.ToArray();
|
||||
|
||||
Assert.AreEqual(4, a.Length);
|
||||
Assert.AreEqual(0, a[0].ID);
|
||||
Assert.AreEqual(1, a[1].ID);
|
||||
Assert.AreEqual(2, a[2].ID);
|
||||
Assert.AreEqual(3, a[3].ID);
|
||||
|
||||
pool.Release(a[1]);
|
||||
|
||||
a = pool.ToArray();
|
||||
|
||||
Assert.AreEqual(3, a.Length);
|
||||
Assert.AreEqual(0, a[0].ID);
|
||||
Assert.AreEqual(2, a[1].ID);
|
||||
Assert.AreEqual(3, a[2].ID);
|
||||
|
||||
pool.Release(a[1]);
|
||||
|
||||
a = pool.ToArray();
|
||||
|
||||
Assert.AreEqual(2, a.Length);
|
||||
Assert.AreEqual(0, a[0].ID);
|
||||
Assert.AreEqual(3, a[1].ID);
|
||||
|
||||
var t2 = pool.Get();
|
||||
|
||||
a = pool.ToArray();
|
||||
|
||||
Assert.AreEqual(3, a.Length);
|
||||
Assert.AreEqual(0, a[0].ID);
|
||||
Assert.AreEqual(2, a[1].ID);
|
||||
Assert.AreEqual(2, t2.ID);
|
||||
Assert.AreEqual(3, a[2].ID);
|
||||
|
||||
var t1 = pool.Get();
|
||||
|
||||
a = pool.ToArray();
|
||||
|
||||
Assert.AreEqual(4, a.Length);
|
||||
Assert.AreEqual(0, a[0].ID);
|
||||
Assert.AreEqual(1, a[1].ID);
|
||||
Assert.AreEqual(1, t1.ID);
|
||||
Assert.AreEqual(2, a[2].ID);
|
||||
Assert.AreEqual(3, a[3].ID);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRestart()
|
||||
{
|
||||
var pool = new TrianglePool();
|
||||
|
||||
Assert.AreEqual(0, pool.Count);
|
||||
Assert.AreEqual(0, pool.Capacity);
|
||||
|
||||
int n = 10;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
Assert.AreEqual(i, pool.Get().ID);
|
||||
}
|
||||
|
||||
Assert.AreEqual(n, pool.Count);
|
||||
|
||||
pool.Restart();
|
||||
|
||||
Assert.AreEqual(0, pool.Count);
|
||||
Assert.AreEqual(10, pool.Capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user