public void DelaunayIncremental() { List <Entity> p = new List <Entity>(); List <Entity> currentPoints = new List <Entity>(); p.AddRange(Points); WingedEdgeMesh mesh = new WingedEdgeMesh(); // We start by making a first triangle mesh.AddVertex(-2.0f, -1.0f, 0.0f); mesh.AddVertex(-2.0f, 5.0f, 0.0f); mesh.AddVertex(2.0f, -1.0f, 0.0f); mesh.AddFace(mesh.Vertices[0], mesh.Vertices[1], mesh.Vertices[2]); // Now, we're going to triangulate vertex per vertex // We get back 1 vertex from the set of vertices, we look for the triangle containing it, then, // we subdivide it in 3 triangles. We then check that every new triangle is Delaunay. If not, we flip/switchover the // opposite edge of the new vertex while (p.Count > 0) { // We start by extracting a point from the set of vertices Entity point = p[0]; p.RemoveAt(0); FaceWE f = null; int findex = 0; // Looking for the triangle that contains the dot for (int i = 0; i < mesh.Faces.Count; i++) { FaceWE currentFace = mesh.Faces[i]; List <VertexWE> vertices = mesh.GetFaceVertices(currentFace); bool isIn = Troll3D.TRaycast.PointInTriangle(vertices[0].Position, vertices[1].Position, vertices[2].Position, point.transform_.position_); if (isIn) { f = currentFace; findex = i; } } // In theory, we should have get back a triangle that contains the vertex. We're now going to divide that // in 3 triangles using the current vertex List <FaceWE> faces = mesh.AddVertex(f, point.transform_.position_.X, point.transform_.position_.Y, point.transform_.position_.Z); // Now we must check that the triangles we found are Delaunay. Meaning that the // circumscribed circle of the triangle must contains only points of the triangle. // Checking the faces created for (int i = 0; i < faces.Count; i++) { InspectEdge(faces[i].Edges, mesh); } } //Removing mesh thing used for triangulation List <FaceWE> faceToRemove = new List <FaceWE>(); for (int i = mesh.Faces.Count - 1; i >= 0; i--) { if (mesh.IsFaceBorder(mesh.Faces[i])) { faceToRemove.Add(mesh.Faces[i]); } } for (int i = 0; i < faceToRemove.Count; i++) { mesh.RemoveFace(faceToRemove[i]); } for (int i = 0; i < CircleCenter.Count; i++) { Scene.CurrentScene.RemoveRenderable(( MeshRenderer )CircleCenter[i].GetComponent(ComponentType.MeshRenderer)); } if (DisplayCenters) { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); for (int i = 0; i < mesh.Faces.Count; i++) { List <VertexWE> vertices = mesh.GetFaceVertices(mesh.Faces[i]); Vector3 circleCenter = GetCircleCenter(vertices[0].Position, vertices[1].Position, vertices[2].Position); float radius = GetCircleRadius(vertices[0].Position, vertices[1].Position, vertices[2].Position, circleCenter); AddCircleCenter(circleCenter.X, circleCenter.Y, radius); } } else { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); } if (mesh.MakeMesh() != null) { meshRenderer.model_ = mesh.MakeMesh(); meshRenderer.SetFillMode(SharpDX.Direct3D11.FillMode.Wireframe); meshRenderer.material_.SetMainColor(1.0f, 0.0f, 0.0f, 1.0f); } else { } if (DisplayVoronoi) { BuildVoronoi(mesh); } else { CleanVoronoi(); } }
/// <summary> /// Implémentation de l'algorithme de triangulation de Delaunay incremental /// </summary> public void DelaunayIncremental() { List <Entity> p = new List <Entity>(); List <Entity> currentPoints = new List <Entity>(); p.AddRange(Points); WingedEdgeMesh mesh = new WingedEdgeMesh(); // On commence par créer un big triangle capable de contenir tout les autres mesh.AddVertex(-2.0f, -1.0f, 0.0f); mesh.AddVertex(-2.0f, 5.0f, 0.0f); mesh.AddVertex(2.0f, -1.0f, 0.0f); mesh.AddFace(mesh.Vertices[0], mesh.Vertices[1], mesh.Vertices[2]); // Maintenant, on va trianguler point par point // On récupère un point de l'ensemble de point, on cherche le triangle qui le contient, // puis, on subdivise en 3 triangles. On vérifie ensuite que chacun des triangles crée est // Delaunay, si ce n'est pas le cas, on flip l'arrête "opposé" au sommet rajouté while (p.Count > 0) { // On commence par extraire le point Entity point = p[0]; p.RemoveAt(0); FaceWE f = null; int findex = 0; // On cherche le triangle qui contient le point for (int i = 0; i < mesh.Faces.Count; i++) { FaceWE currentFace = mesh.Faces[i]; List <VertexWE> vertices = mesh.GetFaceVertices(currentFace); bool isIn = Troll3D.TRaycast.PointInTriangle(vertices[0].Position, vertices[1].Position, vertices[2].Position, point.transform_.position_); if (isIn) { f = currentFace; findex = i; } } // En théorie, on a récupéré le triangle qui contient le point, on va désormais diviser // ce triangle en 3 en utilisant le point actuel List <FaceWE> faces = mesh.AddVertex(f, point.transform_.position_.X, point.transform_.position_.Y, point.transform_.position_.Z); // Maintenant, on doit vérifier que les triangles obtenus sont delaunay, c'est à dire // que le cercle circonscrit au triangle ne contienne que des points du triangle // On inspecte les faces crées for (int i = 0; i < faces.Count; i++) { InspectEdge(faces[i].Edges, mesh); } } // Je retire les parties du maillage qui sont utilisé pour construire la triangulation List <FaceWE> faceToRemove = new List <FaceWE>(); for (int i = mesh.Faces.Count - 1; i >= 0; i--) { if (mesh.IsFaceBorder(mesh.Faces[i])) { faceToRemove.Add(mesh.Faces[i]); } } for (int i = 0; i < faceToRemove.Count; i++) { mesh.RemoveFace(faceToRemove[i]); } for (int i = 0; i < CircleCenter.Count; i++) { Scene.CurrentScene.RemoveRenderable(( MeshRenderer )CircleCenter[i].GetComponent(ComponentType.MeshRenderer)); } if (DisplayCenters) { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); for (int i = 0; i < mesh.Faces.Count; i++) { List <VertexWE> vertices = mesh.GetFaceVertices(mesh.Faces[i]); Vector3 circleCenter = GetCircleCenter(vertices[0].Position, vertices[1].Position, vertices[2].Position); float radius = GetCircleRadius(vertices[0].Position, vertices[1].Position, vertices[2].Position, circleCenter); AddCircleCenter(circleCenter.X, circleCenter.Y, radius); } } else { for (int i = 0; i < Circles.Count; i++) { Scene.CurrentScene.RemoveRenderable(( LineRenderer )Circles[i].GetComponent(ComponentType.LineRenderer)); } CircleCenter.Clear(); } if (mesh.MakeMesh() != null) { meshRenderer.model_ = mesh.MakeMesh(); meshRenderer.SetFillMode(SharpDX.Direct3D11.FillMode.Wireframe); meshRenderer.material_.SetMainColor(1.0f, 0.0f, 0.0f, 1.0f); } else { } if (DisplayVoronoi) { BuildVoronoi(mesh); } else { CleanVoronoi(); } }