/// <summary> /// We distinguish five types of vertices. Four of these types are /// turn vertices. They are defined as follows: A vertex v is a /// start vertex if its two neighbours lie below it and the interior /// angle at v is less the pi; if the interior angle is greater than /// pi then v is a split vertex. (if both neighbours lie below v, /// then the interior angle cannot be exacly pi. A vertex is an end /// vertex if its two neighbours lie above it and the intertior angle /// at v is less that pi; if the interior angle is greater than pi /// then v is a merge vertex. The vertices that are not turn vertices /// are regular vertices. Thus a regular vertex has one of its /// neighbours above it and one below it. These names have been chosen /// because the algorithm will use a downward plane sweep. /// </summary> /// <param name="vb">The vertex whose type is to be determined</param> /// <returns>The type of the vertex</returns> private VertexType GetVertexType(TVertex vb) { // TODO: Only works for polygons! Debug.Assert(vb.Degree == 2); // TODO: Make this more efficient VertexBase va = vb.Edges.First().Target; VertexBase vc = vb.Edges.Last().Target; Point2D a = ((IPositioned2D)va).Position; Point2D b = vb.Position; Point2D c = ((IPositioned2D)vc).Position; if (yComparer.Compare(a, b) == 0 && yComparer.Compare(c, b) == 0) { return(VertexType.Collinear); } if (yxComparer.Compare(a, b) < 0) { if (yxComparer.Compare(c, b) < 0) { return(LeftTurn(a, b, c) ? VertexType.Start : VertexType.Split); } return(VertexType.Regular); } if (yxComparer.Compare(b, c) < 0) { return(LeftTurn(a, b, c) ? VertexType.End : VertexType.Merge); } return(VertexType.Regular); }
public void BracedQuadilateral() { VertexBase vA = new VertexBase(); VertexBase vB = new VertexBase(); VertexBase vC = new VertexBase(); VertexBase vD = new VertexBase(); mesh.Add(vA); mesh.Add(vB); mesh.Add(vC); mesh.Add(vD); EdgeBase eA = mesh.AddEdge(vA, vB); EdgeBase eB = mesh.AddEdge(vB, vC); EdgeBase eC = mesh.AddEdge(vC, vD); EdgeBase eD = mesh.AddEdge(vD, vA); EdgeBase brace = mesh.AddEdge(vA, vC); Assert.AreNotSame(eA, eB); Assert.AreNotSame(eB, eC); Assert.AreNotSame(eC, eD); Assert.AreNotSame(eD, eA); Assert.AreNotEqual(eA, brace); Assert.AreEqual(4, mesh.VertexCount); Assert.AreEqual(5, mesh.EdgeCount); Assert.AreEqual(0, mesh.FaceCount); Assert.AreEqual(3, vA.Degree); Assert.AreEqual(2, vB.Degree); Assert.AreEqual(3, vC.Degree); Assert.AreEqual(2, vD.Degree); }
/// <summary> /// /// </summary> /// <param name="control"></param> /// <param name="toggle"></param> public virtual void SelectVertex(VertexControl control, bool toggle) { if (control == null) { return; } VertexBase vertex = (VertexBase)control.Vertex; if (selected_vertices_.Contains(vertex)) { if (toggle) { control.SetValue(Selector.IsSelectedProperty, false); DragBehaviour.SetIsTagged(control, false); selected_vertices_.Remove(vertex); vertex_controls_.Remove(vertex); } } else { control.SetValue(Selector.IsSelectedProperty, true); DragBehaviour.SetIsTagged(control, true); selected_vertices_.Add(vertex); vertex_controls_.Add(vertex, control); } }
void RestoreStoreDataInVertexes() { foreach (IVertex v in VertexIdentifiersDictionary.Values) { VertexBase vb = (VertexBase)v; vb._store = this; } }
void NullStoreDataInVertexes() { foreach (IVertex v in VertexIdentifiersDictionary.Values) { VertexBase vb = (VertexBase)v; vb._store = null; } }
public void SingleIsolatedVertex() { VertexBase vA = new VertexBase(); mesh.Add(vA); Assert.AreEqual(1, mesh.VertexCount); Assert.IsTrue(vA.IsIsolated); }
public void TwoIsolatedVertices() { VertexBase vA = new VertexBase(); VertexBase vB = new VertexBase(); mesh.Add(vA); mesh.Add(vB); Assert.AreEqual(2, mesh.VertexCount); Assert.IsTrue(vA.IsIsolated); Assert.IsTrue(vB.IsIsolated); }
public virtual VertexBase <T> Other(VertexBase <T> vertex) { if (vertex == From) { return(To); } if (vertex == To) { return(From); } return(null); }
/// <summary> /// /// </summary> /// <param name="control"></param> public virtual void UnselectVertex(VertexControl control) { if (control == null) { return; } VertexBase vertex = (VertexBase)control.Vertex; control.SetValue(Selector.IsSelectedProperty, false); DragBehaviour.SetIsTagged(control, false); selected_vertices_.Remove(vertex); vertex_controls_.Remove(vertex); }
public void DuplicateEdge() { VertexBase vA = new VertexBase(); VertexBase vB = new VertexBase(); mesh.Add(vA); mesh.Add(vB); EdgeBase edge1 = new EdgeBase(); EdgeBase actualEdge1 = mesh.AddEdge(vA, vB, edge1); EdgeBase edge2 = new EdgeBase(); EdgeBase actualEdge2 = mesh.AddEdge(vA, vB, edge2); Assert.AreSame(edge1, actualEdge1); Assert.AreSame(actualEdge1, actualEdge2); Assert.AreNotSame(edge2, actualEdge2); }
public void SingleEdge() { VertexBase vA = new VertexBase(); VertexBase vB = new VertexBase(); mesh.Add(vA); mesh.Add(vB); EdgeBase edge = new EdgeBase(); EdgeBase actualEdge = mesh.AddEdge(vA, vB, edge); Assert.AreEqual(2, mesh.VertexCount); Assert.AreEqual(1, mesh.EdgeCount); Assert.IsFalse(vA.IsIsolated); Assert.IsFalse(vB.IsIsolated); Assert.AreSame(edge, actualEdge); Assert.AreSame(vA, edge.Source); Assert.AreSame(vB, edge.Target); }
public void Tetrahedron() { VertexBase vA = new VertexBase(); VertexBase vB = new VertexBase(); VertexBase vC = new VertexBase(); VertexBase vD = new VertexBase(); mesh.Add(vA); mesh.Add(vB); mesh.Add(vC); mesh.Add(vD); EdgeBase e1 = mesh.AddEdge(vA, vB); EdgeBase e2 = mesh.AddEdge(vB, vC); EdgeBase e3 = mesh.AddEdge(vC, vA); EdgeBase e4 = mesh.AddEdge(vA, vD); EdgeBase e5 = mesh.AddEdge(vB, vD); EdgeBase e6 = mesh.AddEdge(vC, vD); FaceBase fa = mesh.AddFace(e1, e2, e3); FaceBase fb = mesh.AddFace(e1, e5, e4); FaceBase fc = mesh.AddFace(e2, e6, e5); FaceBase fd = mesh.AddFace(e3, e4, e6); Assert.AreNotEqual(e1, e2); Assert.AreNotEqual(e2, e3); Assert.AreNotEqual(e3, e4); Assert.AreNotEqual(e4, e5); Assert.AreNotEqual(e5, e6); Assert.AreEqual(3, vA.Degree); Assert.AreEqual(3, vB.Degree); Assert.AreEqual(3, vC.Degree); Assert.AreEqual(3, vD.Degree); Assert.AreEqual(4, mesh.VertexCount); Assert.AreEqual(6, mesh.EdgeCount); Assert.AreEqual(3, fa.EdgeCount); Assert.AreEqual(3, fb.EdgeCount); Assert.AreEqual(3, fc.EdgeCount); Assert.AreEqual(3, fd.EdgeCount); }
public void Triangle() { VertexBase vA = new VertexBase(); VertexBase vB = new VertexBase(); VertexBase vC = new VertexBase(); mesh.Add(vA); mesh.Add(vB); mesh.Add(vC); EdgeBase eA = mesh.AddEdge(vB, vC); EdgeBase eB = mesh.AddEdge(vC, vA); EdgeBase eC = mesh.AddEdge(vA, vB); Assert.AreNotSame(eA, eB); Assert.AreNotSame(eB, eC); Assert.AreNotSame(eC, eA); Assert.AreEqual(2, vA.Degree); Assert.AreEqual(2, vB.Degree); Assert.AreEqual(2, vC.Degree); }
private static bool NextNeighbour(Grapher <VertexBase> graph, HashSet <VertexBase> discoveredVertices, VertexBase source, VertexBase target) { if (IsVertexDiscovered(discoveredVertices, target)) { return(true); } DiscoverVertex(discoveredVertices, target); foreach (var v in graph.Neighbours(target)) { if (v.Name == source.Name) { continue; } if (NextNeighbour(graph, discoveredVertices, target, v)) { return(true); } } return(false); }
public bool IsBetween(VertexBase <T> a, VertexBase <T> b) { return(a == From && b == To || a == To && b == From); }
public DataEdge(VertexBase <T> from, VertexBase <T> to, TData data) : base(from, to) { Data = data; }
public DirectedEdge(VertexBase <T> from, VertexBase <T> to) : base(from, to) { }
public DirectedDataEdge(VertexBase <T> from, VertexBase <T> to, TData data) : base(from, to, data) { }
public override VertexBase <T> Other(VertexBase <T> vertexOld) { return(vertexOld == From ? To : null); }
private static bool IsVertexDiscovered(HashSet <VertexBase> discoveredVertices, VertexBase v) { return(discoveredVertices.Contains(v)); }
private static void DiscoverVertex(HashSet <VertexBase> discoveredVertices, VertexBase v) { discoveredVertices.Add(v); }
public static List <VertexBase> FindShortestPath(Grapher <VertexBase> graph, VertexBase startVertex, VertexBase endVertex) { Grapher <DijkstraVertex> G = ConvertToDijkstraGraph(graph); DijkstraVertex s = G.VertexForName(startVertex.Name); DijkstraVertex n = G.VertexForName(endVertex.Name); // Active set var A = new List <DijkstraVertex>(); // Non-active set var N = new List <DijkstraVertex>(); var predecessorList = new Dictionary <DijkstraVertex, DijkstraVertex>(); var lastVertex = s; foreach (var p in G.Vertices) { predecessorList.Add(p, null); } // Init s.Distance = 0; A.AddRange(G.Vertices); A = A.OrderBy(x => x.Distance).ToList(); if (s.Name == n.Name) { Debug.WriteLine("Start and endnote is equal, returning!"); return(new List <VertexBase>()); } //var handleMap = A.AddRange(G.Vertices); for (int i = 0; i < A.Count;) { var v = A.ElementAt(i); if (v.Distance != double.PositiveInfinity) { double min = A[0].Distance; for (int j = 0; j < A.Count; j++) { if (A.ElementAt(j).Distance == min) { N.Add(A.ElementAt(j)); i++; } } foreach (var d in N) // N needs to be cleared after each iteration { Debug.WriteLine("Node finished: " + d.Name + ", Distance:" + d.Distance); A.Remove(d); i--; } foreach (var e in G.Edges) { if (N.Contains(e.V1) && A.Contains(e.V0)) { var d = e.V1.Distance + e.Weight; if (d < e.V0.Distance) { e.V0.Distance = d; predecessorList[e.V0] = e.V1; //Add actual predecessor to e.v0 } Debug.WriteLine("New Distance for " + e.V0.Name + ": " + e.V0.Distance); } else if (N.Contains(e.V0) && A.Contains(e.V1)) { var d = e.V0.Distance + e.Weight; if (d < e.V1.Distance) { e.V1.Distance = d; predecessorList[e.V1] = e.V0; //Add actual predecessor to e.v0 } Debug.WriteLine("New Distance for " + e.V1.Name + ": " + e.V1.Distance); } } A = A.OrderBy(x => x.Distance).ToList(); N.Clear(); } } List <VertexBase> shortestPath = new List <VertexBase>(); var actualPredecessor = predecessorList[n]; if (predecessorList[n].Name == s.Name) // Path only has EndVertex and StartVertex -> finished! { shortestPath.Add(n); shortestPath.Add(s); return(shortestPath); } else { shortestPath.Add(n); // Find shortest path to endVertex while (actualPredecessor.Name != s.Name) { if (predecessorList[actualPredecessor].Name == s.Name) // Predecessor of actual predecessor is s -> finished! { shortestPath.Add(actualPredecessor); shortestPath.Add(s); return(shortestPath); } else { shortestPath.Add(actualPredecessor); } actualPredecessor = predecessorList[actualPredecessor]; } } return(null); }
public Edge(VertexBase <T> from, VertexBase <T> to) { From = from; To = to; }