Example #1
0
        /// <summary>
        /// Construit une représentation graphique du Diagramme de Voronoi de la triangulation
        /// </summary>
        public void BuildVoronoi(WingedEdgeMesh mesh)
        {
            List <StandardVertex> lines = new List <StandardVertex>();

            // On va commencer par construire les sommets correspondant aux centre des faces de la triangulation
            // qui sont les noeuds du diagramme de voronoir
            CleanVoronoi();

            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                // On récupère le centre de la face (barycentre)

                List <VertexWE> vertices = mesh.GetFaceVertices(mesh.Faces[i]);

                Vector3 center = vertices[0].Position + vertices[1].Position + vertices[2].Position;
                center = center / 3.0f;

                Troll3D.Entity entity = new Troll3D.Entity(Entity);
                entity.transform_.SetPosition(
                    center.X,
                    center.Y,
                    0.0f);

                entity.transform_.SetScale(0.02f, 0.02f, 1.0f);

                MaterialDX11 material = new MaterialDX11();
                material.SetMainColor(0.0f, 1.0f, 1.0f, 1.0f);
                MeshRenderer meshrenderer = entity.AddComponent <MeshRenderer>();
                meshrenderer.material_ = material;
                meshrenderer.model_    = Quad.GetMesh();

                // On récupère les voisins

                List <FaceWE> neighbours = mesh.GetFaceNeighbours(mesh.Faces[i]);

                for (int j = 0; j < neighbours.Count; j++)
                {
                    // On récupère le centre de la face (barycentre)

                    List <VertexWE> verticesNeighbour = mesh.GetFaceVertices(neighbours[j]);

                    Vector3 centerNeighbour = verticesNeighbour[0].Position + verticesNeighbour[1].Position + verticesNeighbour[2].Position;
                    centerNeighbour = centerNeighbour / 3.0f;

                    lines.Add(new StandardVertex(center));
                    lines.Add(new StandardVertex(centerNeighbour));
                }

                VoronoiPoints.Add(entity);
            }

            if (lines.Count > 0)
            {
                (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).Display  = true;
                (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).Vertices = lines;
                (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).UpdateRenderer();
            }
        }
        public void BuildVoronoi(WingedEdgeMesh mesh)
        {
            List <StandardVertex> lines = new List <StandardVertex>();

            // We start by building the vertices corresponding to the face's center of the triangulation who are node of the Voronoi diagram
            CleanVoronoi();

            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                // We get back the face's center (barycentre)

                List <VertexWE> vertices = mesh.GetFaceVertices(mesh.Faces[i]);

                Vector3 center = vertices[0].Position + vertices[1].Position + vertices[2].Position;
                center = center / 3.0f;

                Troll3D.Entity entity = new Troll3D.Entity(Entity);
                entity.transform_.SetPosition(
                    center.X,
                    center.Y,
                    0.0f);

                entity.transform_.SetScale(0.02f, 0.02f, 1.0f);

                MaterialDX11 material = new MaterialDX11();
                material.SetMainColor(0.0f, 1.0f, 1.0f, 1.0f);
                MeshRenderer meshrenderer = entity.AddComponent <MeshRenderer>();
                meshrenderer.material_ = material;
                meshrenderer.model_    = Quad.GetMesh();

                // We get back the neighbours

                List <FaceWE> neighbours = mesh.GetFaceNeighbours(mesh.Faces[i]);

                for (int j = 0; j < neighbours.Count; j++)
                {
                    // On récupère le centre de la face (barycentre)

                    List <VertexWE> verticesNeighbour = mesh.GetFaceVertices(neighbours[j]);

                    Vector3 centerNeighbour = verticesNeighbour[0].Position + verticesNeighbour[1].Position + verticesNeighbour[2].Position;
                    centerNeighbour = centerNeighbour / 3.0f;

                    lines.Add(new StandardVertex(center));
                    lines.Add(new StandardVertex(centerNeighbour));
                }

                VoronoiPoints.Add(entity);
            }

            if (lines.Count > 0)
            {
                (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).Display  = true;
                (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).Vertices = lines;
                (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).UpdateRenderer();
            }
        }
 public void CleanVoronoi()
 {
     for (int i = 0; i < VoronoiPoints.Count; i++)
     {
         Scene.CurrentScene.RemoveRenderable(( MeshRenderer )VoronoiPoints[i].GetComponent(ComponentType.MeshRenderer));
     }
     VoronoiPoints.Clear();
     (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).Display = false;
 }
Example #4
0
 public void CleanVoronoi()
 {
     // On commence par "effacer" les derniers points
     for (int i = 0; i < VoronoiPoints.Count; i++)
     {
         Scene.CurrentScene.RemoveRenderable(( MeshRenderer )VoronoiPoints[i].GetComponent(ComponentType.MeshRenderer));
     }
     VoronoiPoints.Clear();
     (( LineRenderer )VoronoiLines.GetComponent(ComponentType.LineRenderer)).Display = false;
 }
Example #5
0
        public void Reorder(int width, int height)
        {
            //Checks if the site is fully included in the frame :
            if (Edges.Select(e => e.VVertexA).All(p => IsVectorInRange(p, width, height)) &&
                Edges.Select(e => e.VVertexB).All(p => IsVectorInRange(p, width, height)))
            {
                IsOnBorder = false;
            }
            else
            {
                IsOnBorder = true;
                Vector previousIntersection = null;
                for (int i = Edges.Count - 1; i >= 0; i--)
                {
                    VoronoiEdge edge  = Edges[i];
                    bool        isAIn = IsVectorInRange(edge.VVertexA, width, height);
                    bool        isBIn = IsVectorInRange(edge.VVertexB, width, height);
                    if (isAIn && isBIn) // Edge is fully in, nothing to do
                    {
                        continue;
                    }
                    if (isAIn || isBIn) // One point in in, needs to be clipped
                    {
                        double        slope         = edge.DirectionVector[1] / edge.DirectionVector[0];
                        Vector        pointIn       = isAIn ? new Vector(edge.VVertexA) : new Vector(edge.VVertexB);
                        List <Vector> intersections = new List <Vector>();
                        //Test collision with (0,0) => (width,0) edge :
                        intersections.Add(new Vector(pointIn[0] - pointIn[1] / slope, 0));
                        //Test collision with (0,height) => (width,height) edge :
                        intersections.Add(new Vector(pointIn[0] + (height - pointIn[1]) / slope, height));
                        //Test collision with (0,0) => (0,height) edge :
                        intersections.Add(new Vector(0, pointIn[1] - pointIn[0] * slope));
                        //Test collision with (width,0) => (width,height) edge :
                        intersections.Add(new Vector(width, pointIn[1] + (width - pointIn[0]) * slope));
                        Vector intersection = intersections.MinBy(p => Vector.Dist(p, pointIn));
                        Edges.RemoveAt(i);
                        Edges.Add(new VoronoiEdge {
                            VVertexA = intersection, VVertexB = pointIn
                        });
                        if (previousIntersection == null)
                        {
                            previousIntersection = intersection;
                        }
                        else
                        {
                            if (intersection[0].Equals(previousIntersection[0]) ||
                                intersection[1].Equals(previousIntersection[1]))
                            {
                                Edges.Add(new VoronoiEdge {
                                    VVertexA = intersection, VVertexB = previousIntersection
                                });
                                IsOnBorder           = true;
                                previousIntersection = null;
                            }
                            else
                            {
                                List <Vector> corners = new List <Vector>
                                {
                                    new Vector(0, 0),
                                    new Vector(width, 0),
                                    new Vector(width, height),
                                    new Vector(0, height)
                                };
                                foreach (Vector corner in corners)
                                {
                                    if ((corner[0].Equals(previousIntersection[0]) ||
                                         corner[0].Equals(intersection[0])) &&
                                        (corner[1].Equals(previousIntersection[1]) ||
                                         corner[1].Equals(intersection[1])))
                                    {
                                        Edges.Add(new VoronoiEdge {
                                            VVertexA = corner, VVertexB = previousIntersection
                                        });
                                        Edges.Add(new VoronoiEdge {
                                            VVertexA = corner, VVertexB = intersection
                                        });
                                        IsOnBorder = true;
                                        break;
                                    }
                                }
                                previousIntersection = null;
                            }
                        }
                    }
                    else // Edge fully out, can be safely removed
                    {
                        Edges.RemoveAt(i);
                    }
                }
                if (previousIntersection != null)
                {
                    throw new InvalidOperationException("Error");
                }
            }
            if (Edges.Count == 0)
            {
                throw new InvalidOperationException("No edges");
            }

            VoronoiEdge first = Edges[Edges.Count - 1];

            Edges.RemoveAt(Edges.Count - 1);
            Vector point;

            VoronoiPoints.Add(point = first.VVertexA);
            Edges.RemoveAll((e) => Equals(e.VVertexA, e.VVertexB));
            do
            {
                VoronoiEdge edge = Edges.Single(e => e.VVertexA.Equals(point) || e.VVertexB.Equals(point));
                Edges.Remove(edge);
                if (Equals(edge.VVertexA, point))
                {
                    VoronoiPoints.Add(point = edge.VVertexB);
                }
                else
                {
                    VoronoiPoints.Add(point = edge.VVertexA);
                }
            } while (!Equals(point, first.VVertexB));
            Edges.Clear();
            //Reverse ordering of the points if needed :
            Vector v1 = VoronoiPoints[0] - VoronoiPoints[1];
            Vector v2 = VoronoiCenter - VoronoiPoints[0];

            if (v1[0] * v2[1] - v1[1] * v2[0] > 0)
            {
                VoronoiPoints.Reverse();
            }
        }