/// <summary>
 /// Creates an edge if it does not exist, or retrieves an edge with v1 and v2 as points if it does exist
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <returns></returns>
 public Edge CreateOrGet(Vertex v1, Vertex v2)
 {
     var edge = v1.Edges.FirstOrDefault(o => o.v1 == v2 || o.v2 == v2);
     if (edge == null)
         edge = CreateEdge(v1, v2);
     return edge;
 }
 /// <summary>
 /// Creates an edge
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <returns></returns>
 public Edge CreateEdge(Vertex v1, Vertex v2)
 {
     Edge result = new Edge() { v1 = v1, v2 = v2 };
     v1.Edges.Add(result);
     v2.Edges.Add(result);
     return result;
 }
예제 #3
0
 /// <summary>
 /// Retriangulate the given triangle with P
 /// Basically removes the conflicting edge from the graph and introduces a new one from the vertex that was not on the removed edge and P
 /// </summary>
 /// <param name="triangle"></param>
 /// <param name="P"></param>
 private void Retriangulate(Triangle triangle, Vertex P)
 {
     var otherVertex = triangle.GetVertices().Single(o => o != triangle.conflictingEdge.v1 && o != triangle.conflictingEdge.v2);
     GM.DestroyEdge(triangle.conflictingEdge);
     GM.CreateOrGet(otherVertex, P);
 }
예제 #4
0
        /// <summary>
        /// Recursively retrieves all conflicting triangles with P based on their circumcircle
        /// This method should be O(S) where S is the number of conflicting triangles, which is constant for a convex polygon
        /// However due to a bug this seems to be untrue.
        /// </summary>
        /// <param name="P"></param>
        /// <param name="currentTriangle"></param>
        /// <param name="SearchNr"></param>
        /// <param name="conflicting"></param>
        /// <returns></returns>
        private List<Triangle> GetRecursiveConflicitingTriangles(Vertex P, Triangle currentTriangle, int SearchNr, Edge conflicting)
        {
            var result = new List<Triangle>();
            if(currentTriangle == null)
                return result;
            currentTriangle.conflictingEdge = conflicting;
            var center = currentTriangle.CreateTriangle().GetCircumCentre();
            if (center.Distance(P.Point) <= center.Distance(currentTriangle.Edges[0].v1.Point))
            {
                //If the circumcircle contains P, add the triangle to the list
                result.Add(currentTriangle);
                //And continue over all triangles adjecent to the current triangles
                foreach (var edge in currentTriangle.Edges)
                {
                    //If the edge was not visited yet, continue
                    if (!edge.VisitedBy.ContainsKey(SearchNr) || !edge.VisitedBy[SearchNr])
                    {
                        edge.VisitedBy[SearchNr] = true;
                        result.AddRange(GetRecursiveConflicitingTriangles(P, edge.GetOtherTriangle(currentTriangle), SearchNr, edge));
                    }
                }

            }
            return result;
        }
 /// <summary>
 /// Generate a random vertex within the given boundaries
 /// </summary>
 /// <param name="xMin"></param>
 /// <param name="xMax"></param>
 /// <param name="yMin"></param>
 /// <param name="yMax"></param>
 /// <returns></returns>
 public static Vertex RandomVertex(int xMin, int xMax, int yMin, int yMax)
 {
     var x = RandomGenerator.Next(xMin, xMax);
     var y = RandomGenerator.Next(yMin, yMax);
     var vertex = new Vertex() { Point = new C2DPoint(x, y)};
     return vertex;
 }
        /// <summary>
        /// Splits an edge on a convex polygon into two edges by adding a vertex on a random position
        /// While keeping the Convex constraint.
        /// </summary>
        /// <param name="gm"></param>
        /// <param name="e"></param>
        /// <param name="maxOffset"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static List<Edge> SplitConvexEdge(GraphManager gm, Edge e, int maxOffset, int index)
        {
            var edgeLine = e.CreateLine();
            List<Edge> result = new List<Edge>();
            //Create random point on the edge
            var offset = Convert.ToDouble(RandomGenerator.Next(0, 100)) / 122 + 0.1;
            var point = edgeLine.GetPointOn(offset);

            //Calculate offsets
            var dx = e.v2.Point.x - e.v1.Point.x;
            var dy = e.v2.Point.y - e.v1.Point.y;

            //Note swapping offsets for X and Y.
            var offsetX = Math.Abs(dx) / (dy);
            var offsetY = Math.Abs(dy) / (dx * -1);

            //Calculate the maximum endpoint for the new node.
            var endPoint = new C2DPoint(offsetX * maxOffset + point.x, offsetY * maxOffset + point.y);
            var newLine = new C2DLine(point, endPoint);

            var otherVertex1 = e.v1;
            var otherVertex2 = e.v2;
            var otherEdge1 = otherVertex1.GetOther(e).CreateLine();
            var otherEdge2 = otherVertex2.GetOther(e).CreateLine();

            //Compare with both  other edges, to check if the new vertex would still result in a convex polygon.
            //If not, update the maximum offset for the new vertex
            if (otherVertex1.GetOther(e) != otherVertex2.GetOther(e))
            {
                var intersections = new List<C2DPoint>();
                otherEdge1.GrowFromCentre(100000000);//Hack: to check if they intersect. The library does not support rays in this case
                if (newLine.Crosses(otherEdge1, intersections))
                {
                    var newEndpoint = intersections.Single();
                    newLine = new C2DLine(point, newEndpoint);
                }
                intersections = new List<C2DPoint>();
                otherEdge2.GrowFromCentre(100000000); //Hack: to check if they intersect. The library does not support rays in this case
                if (newLine.Crosses(otherEdge2, intersections))
                {
                    var newEndpoint = intersections.Single();
                    newLine = new C2DLine(point, newEndpoint);
                }
            }

            //Select a random point on the line (which is bound)
            var newlineOffset = Convert.ToDouble(RandomGenerator.Next(0, 100)) / 122+0.1;
            var newPoint = newLine.GetPointOn(offset);

            var newVertex = new Vertex() { Point = newPoint };
            //Indexof might be very slow? Note this is just used for the creation of a testvertex
            gm.AddVertexAt(newVertex, gm.Vertices.IndexOf(otherVertex2));
            gm.DestroyEdge(e);//Unregister the old edge
            result.Add(gm.CreateEdge(otherVertex1, newVertex)); //Add the two new ones
            result.Add(gm.CreateEdge(newVertex, otherVertex2)); // :)
            return result;
        }
 /// <summary>
 /// Creates a new triangle on the given vertices
 /// Creades the edges if needed
 /// Updates references on existing edges
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <param name="v3"></param>
 /// <returns></returns>
 public Triangle CreateTriangleAndEdges(Vertex v1, Vertex v2, Vertex v3)
 {
     var triangle = new Triangle();
     var edge1 = CreateOrGet(v1, v2);
     var edge2 = CreateOrGet(v2, v3);
     var edge3 = CreateOrGet(v3, v1);
     triangle.Edges.Add(edge1);
     triangle.Edges.Add(edge2);
     triangle.Edges.Add(edge3);
     return triangle;
 }
 /// <summary>
 /// Inserts a vertex into the list at a specific location
 /// </summary>
 /// <param name="vertex"></param>
 /// <param name="index"></param>
 public void AddVertexAt(Vertex vertex, int index)
 {
     Vertices.Insert(index, vertex);
 }
 /// <summary>
 /// Adds a vertex to the end of the list
 /// </summary>
 /// <param name="vertex"></param>
 public void AddVertex(Vertex vertex)
 {
     Vertices.Add(vertex);
 }
예제 #10
0
 public Edge <TData, TMetric> EdgeForVertex(Vertex <TData, TMetric> vertex)
 {
     return(Vertices[vertex]);
 }
예제 #11
0
 public bool Contains(Vertex <TData, TMetric> vertex)
 {
     return(Vertices.ContainsKey(vertex));
 }