private static Sphere GetCircumsphere(Tetrahedron tetra) { var p = tetra.p; float[][] a = new float[][] { new float[] { p[1].x - p[0].x, p[1].y - p[0].y, p[1].z - p[0].z }, new float[] { p[2].x - p[0].x, p[2].y - p[0].y, p[2].z - p[0].z }, new float[] { p[3].x - p[0].x, p[3].y - p[0].y, p[3].z - p[0].z } }; float[] b = { 0.5f * (p[1].x * p[1].x - p[0].x * p[0].x + p[1].y * p[1].y - p[0].y * p[0].y + p[1].z * p[1].z - p[0].z * p[0].z), 0.5f * (p[2].x * p[2].x - p[0].x * p[0].x + p[2].y * p[2].y - p[0].y * p[0].y + p[2].z * p[2].z - p[0].z * p[0].z), 0.5f * (p[3].x * p[3].x - p[0].x * p[0].x + p[3].y * p[3].y - p[0].y * p[0].y + p[3].z * p[3].z - p[0].z * p[0].z) }; float[] x = { 0f, 0f, 0f }; var det = Gauss(a, b, ref x); if (det == 0) { return(new Sphere(Vector3.zero, -1)); } else { var center = new Vector3(x[0], x[1], x[2]); return(new Sphere(center, Vector3.Distance(center, p[0]))); } }
private static List <Triangle> GetDelaunayTriangles(List <Vector3> vertices) { var tetras = new HashSet <Tetrahedron>(); Tetrahedron huge = GetHugeTetrahedron(vertices); tetras.Add(huge); foreach (var v in vertices) { var counter = new Counter <Tetrahedron>(); var trash = new List <Tetrahedron>(); foreach (var t in tetras) { var sphere = GetCircumsphere(t); if (Vector3.Distance(sphere.center, v) < sphere.radius) { counter.Add(new Tetrahedron(v, t.p[0], t.p[1], t.p[2])); counter.Add(new Tetrahedron(v, t.p[0], t.p[2], t.p[3])); counter.Add(new Tetrahedron(v, t.p[0], t.p[1], t.p[3])); counter.Add(new Tetrahedron(v, t.p[1], t.p[2], t.p[3])); trash.Add(t); } } tetras.RemoveWhere(t => trash.Contains(t)); foreach (KeyValuePair <Tetrahedron, int> entry in counter) { if (entry.Value == 1) { tetras.Add(entry.Key); } } } tetras.RemoveWhere(t => huge.ShareVertex(t)); var triangles = new HashSet <Triangle>(); foreach (var t in tetras) { triangles.Add(new Triangle(t.p[0], t.p[1], t.p[2])); triangles.Add(new Triangle(t.p[0], t.p[2], t.p[3])); triangles.Add(new Triangle(t.p[0], t.p[1], t.p[3])); triangles.Add(new Triangle(t.p[1], t.p[2], t.p[3])); } return(triangles.ToList()); }